[Pkg-voip-commits] r5512 - in /freepbx-modules/trunk/modules: announcement/ asterisk-cli/ asteriskinfo/ backup/ backup/bin/ blacklist/ callback/ callback/bin/ callforward/ callwaiting/ cidlookup/ conferences/ core/ core/agi-bin/ core/bin/ core/etc/ customerdb/ dashboard/ dashboard/images/ dashboard/phpsysinfo/ daynight/ daynight/i18n/ dictate/ dictate/sounds/ disa/ donotdisturb/ featurecodeadmin/ findmefollow/ gabcast/ infoservices/ inventorydb/ ivr/ logfiles/ manager/ miscapps/ miscdests/ music/ paging/ parking/ pbdirectory/ pbdirectory/agi-bin/ phonebook/ phpagiconf/ phpinfo/ pinsets/ printextensions/ queues/ recordings/ recordings/images/ ringgroups/ speeddial/ timeconditions/ voicemail/

tzafrir-guest at alioth.debian.org tzafrir-guest at alioth.debian.org
Mon Apr 7 13:18:06 UTC 2008


Author: tzafrir-guest
Date: Mon Apr  7 13:18:05 2008
New Revision: 5512

URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=5512
Log:
FreePBX 2.3.1 modules .

Not tested yet to build, but it seems I must commit those to get past
svn-buildpackage :-( .

Added:
    freepbx-modules/trunk/modules/backup/install.php
    freepbx-modules/trunk/modules/backup/uninstall.php
    freepbx-modules/trunk/modules/callback/bin/
    freepbx-modules/trunk/modules/callback/bin/callback   (with props)
    freepbx-modules/trunk/modules/core/
    freepbx-modules/trunk/modules/core/XML_Parser.php
    freepbx-modules/trunk/modules/core/XML_Unserializer.php
    freepbx-modules/trunk/modules/core/agi-bin/
    freepbx-modules/trunk/modules/core/agi-bin/checksound.agi   (with props)
    freepbx-modules/trunk/modules/core/agi-bin/dialparties.agi   (with props)
    freepbx-modules/trunk/modules/core/agi-bin/directory   (with props)
    freepbx-modules/trunk/modules/core/agi-bin/enumlookup.agi   (with props)
    freepbx-modules/trunk/modules/core/agi-bin/fixlocalprefix   (with props)
    freepbx-modules/trunk/modules/core/agi-bin/list-item-remove.php   (with props)
    freepbx-modules/trunk/modules/core/agi-bin/recordingcheck   (with props)
    freepbx-modules/trunk/modules/core/bin/
    freepbx-modules/trunk/modules/core/bin/fax-process.pl   (with props)
    freepbx-modules/trunk/modules/core/etc/
    freepbx-modules/trunk/modules/core/etc/extensions.conf
    freepbx-modules/trunk/modules/core/etc/iax.conf
    freepbx-modules/trunk/modules/core/etc/sip.conf
    freepbx-modules/trunk/modules/core/functions.inc.php
    freepbx-modules/trunk/modules/core/install.php
    freepbx-modules/trunk/modules/core/module.xml
    freepbx-modules/trunk/modules/core/page.ampusers.php
    freepbx-modules/trunk/modules/core/page.devices.php
    freepbx-modules/trunk/modules/core/page.did.php
    freepbx-modules/trunk/modules/core/page.extensions.php
    freepbx-modules/trunk/modules/core/page.general.php
    freepbx-modules/trunk/modules/core/page.routing.php
    freepbx-modules/trunk/modules/core/page.trunks.php
    freepbx-modules/trunk/modules/core/page.users.php
    freepbx-modules/trunk/modules/dashboard/
    freepbx-modules/trunk/modules/dashboard/class.astinfo.php
    freepbx-modules/trunk/modules/dashboard/class.average_rate_calculator.php
    freepbx-modules/trunk/modules/dashboard/class.error.inc.php
    freepbx-modules/trunk/modules/dashboard/class.procinfo.php
    freepbx-modules/trunk/modules/dashboard/dashboard.css
    freepbx-modules/trunk/modules/dashboard/functions.inc.php
    freepbx-modules/trunk/modules/dashboard/images/
    freepbx-modules/trunk/modules/dashboard/images/dashboard-sysinfo.png   (with props)
    freepbx-modules/trunk/modules/dashboard/images/notify_critical.png   (with props)
    freepbx-modules/trunk/modules/dashboard/images/notify_delete.png   (with props)
    freepbx-modules/trunk/modules/dashboard/images/notify_error.png   (with props)
    freepbx-modules/trunk/modules/dashboard/images/notify_notice.png   (with props)
    freepbx-modules/trunk/modules/dashboard/images/notify_security.png   (with props)
    freepbx-modules/trunk/modules/dashboard/images/notify_update.png   (with props)
    freepbx-modules/trunk/modules/dashboard/images/notify_warning.png   (with props)
    freepbx-modules/trunk/modules/dashboard/module.xml
    freepbx-modules/trunk/modules/dashboard/page.index.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.BSD.common.inc.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.Darwin.inc.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.FreeBSD.inc.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.HP-UX.inc.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.Linux.inc.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.NetBSD.inc.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.OpenBSD.inc.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.SunOS.inc.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.WINNT.inc.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.parseProgs.inc.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/common_functions.php
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/distros.ini
    freepbx-modules/trunk/modules/dashboard/phpsysinfo/index.html
    freepbx-modules/trunk/modules/daynight/
    freepbx-modules/trunk/modules/daynight/functions.inc.php
    freepbx-modules/trunk/modules/daynight/i18n/
    freepbx-modules/trunk/modules/daynight/install.php
    freepbx-modules/trunk/modules/daynight/module.xml
    freepbx-modules/trunk/modules/daynight/page.daynight.php
    freepbx-modules/trunk/modules/daynight/uninstall.php
    freepbx-modules/trunk/modules/dictate/sounds/dictation-being-processed.sln   (with props)
    freepbx-modules/trunk/modules/dictate/sounds/dictation-sent.sln   (with props)
    freepbx-modules/trunk/modules/inventorydb/install.php
    freepbx-modules/trunk/modules/manager/install.php
    freepbx-modules/trunk/modules/miscapps/install.php
    freepbx-modules/trunk/modules/miscapps/uninstall.sql
    freepbx-modules/trunk/modules/miscdests/install.php
    freepbx-modules/trunk/modules/paging/uninstall.php
    freepbx-modules/trunk/modules/parking/install.php
    freepbx-modules/trunk/modules/queues/install.php
    freepbx-modules/trunk/modules/recordings/audio.php
    freepbx-modules/trunk/modules/recordings/crypt.php
    freepbx-modules/trunk/modules/recordings/images/
    freepbx-modules/trunk/modules/recordings/images/play.png   (with props)
    freepbx-modules/trunk/modules/recordings/popup.css
    freepbx-modules/trunk/modules/recordings/popup.php
    freepbx-modules/trunk/modules/timeconditions/install.php
    freepbx-modules/trunk/modules/timeconditions/uninstall.sql
Removed:
    freepbx-modules/trunk/modules/logfiles/asterisk-full-log.php
    freepbx-modules/trunk/modules/logfiles/logfiles.php
    freepbx-modules/trunk/modules/paging/phones.sql
    freepbx-modules/trunk/modules/phpinfo/phpinfo.inc.php
    freepbx-modules/trunk/modules/timeconditions/unistall.sql
Modified:
    freepbx-modules/trunk/modules/announcement/functions.inc.php
    freepbx-modules/trunk/modules/announcement/install.php
    freepbx-modules/trunk/modules/announcement/module.xml
    freepbx-modules/trunk/modules/announcement/page.announcement.php
    freepbx-modules/trunk/modules/asterisk-cli/module.xml
    freepbx-modules/trunk/modules/asterisk-cli/page.cli.php
    freepbx-modules/trunk/modules/asteriskinfo/module.xml
    freepbx-modules/trunk/modules/asteriskinfo/page.asteriskinfo.php
    freepbx-modules/trunk/modules/backup/bin/ampbackup.pl
    freepbx-modules/trunk/modules/backup/bin/dumpastdb.php
    freepbx-modules/trunk/modules/backup/bin/restoreastdb.php
    freepbx-modules/trunk/modules/backup/bin/retrieve_backup_cron_from_mysql.pl
    freepbx-modules/trunk/modules/backup/module.xml
    freepbx-modules/trunk/modules/backup/schedule_functions.php
    freepbx-modules/trunk/modules/blacklist/functions.inc.php
    freepbx-modules/trunk/modules/blacklist/module.xml
    freepbx-modules/trunk/modules/blacklist/page.blacklist.php
    freepbx-modules/trunk/modules/callback/install.php
    freepbx-modules/trunk/modules/callback/install.sql
    freepbx-modules/trunk/modules/callback/module.xml
    freepbx-modules/trunk/modules/callforward/functions.inc.php
    freepbx-modules/trunk/modules/callforward/module.xml
    freepbx-modules/trunk/modules/callforward/uninstall.php
    freepbx-modules/trunk/modules/callwaiting/functions.inc.php
    freepbx-modules/trunk/modules/callwaiting/module.xml
    freepbx-modules/trunk/modules/cidlookup/functions.inc.php
    freepbx-modules/trunk/modules/cidlookup/install.php
    freepbx-modules/trunk/modules/cidlookup/install.sql
    freepbx-modules/trunk/modules/cidlookup/module.xml
    freepbx-modules/trunk/modules/cidlookup/uninstall.sql
    freepbx-modules/trunk/modules/conferences/functions.inc.php
    freepbx-modules/trunk/modules/conferences/module.xml
    freepbx-modules/trunk/modules/customerdb/module.xml
    freepbx-modules/trunk/modules/dictate/functions.inc.php
    freepbx-modules/trunk/modules/dictate/module.xml
    freepbx-modules/trunk/modules/disa/functions.inc.php
    freepbx-modules/trunk/modules/disa/install.php
    freepbx-modules/trunk/modules/disa/module.xml
    freepbx-modules/trunk/modules/donotdisturb/functions.inc.php
    freepbx-modules/trunk/modules/donotdisturb/module.xml
    freepbx-modules/trunk/modules/donotdisturb/uninstall.php
    freepbx-modules/trunk/modules/featurecodeadmin/module.xml
    freepbx-modules/trunk/modules/findmefollow/functions.inc.php
    freepbx-modules/trunk/modules/findmefollow/install.php
    freepbx-modules/trunk/modules/findmefollow/install.sql
    freepbx-modules/trunk/modules/findmefollow/module.xml
    freepbx-modules/trunk/modules/findmefollow/page.findmefollow.php
    freepbx-modules/trunk/modules/findmefollow/uninstall.php
    freepbx-modules/trunk/modules/gabcast/functions.inc.php
    freepbx-modules/trunk/modules/gabcast/module.xml
    freepbx-modules/trunk/modules/gabcast/page.gabcast.php
    freepbx-modules/trunk/modules/infoservices/functions.inc.php
    freepbx-modules/trunk/modules/infoservices/module.xml
    freepbx-modules/trunk/modules/inventorydb/install.sql
    freepbx-modules/trunk/modules/inventorydb/module.xml
    freepbx-modules/trunk/modules/inventorydb/page.inventorydb.php
    freepbx-modules/trunk/modules/inventorydb/uninstall.sql
    freepbx-modules/trunk/modules/ivr/functions.inc.php
    freepbx-modules/trunk/modules/ivr/install.php
    freepbx-modules/trunk/modules/ivr/module.xml
    freepbx-modules/trunk/modules/ivr/page.ivr.php
    freepbx-modules/trunk/modules/logfiles/module.xml
    freepbx-modules/trunk/modules/logfiles/page.logfiles.php
    freepbx-modules/trunk/modules/manager/install.sql
    freepbx-modules/trunk/modules/manager/module.xml
    freepbx-modules/trunk/modules/manager/uninstall.sql
    freepbx-modules/trunk/modules/miscapps/functions.inc.php
    freepbx-modules/trunk/modules/miscapps/install.sql
    freepbx-modules/trunk/modules/miscapps/module.xml
    freepbx-modules/trunk/modules/miscapps/page.miscapps.php
    freepbx-modules/trunk/modules/miscdests/install.sql
    freepbx-modules/trunk/modules/miscdests/module.xml
    freepbx-modules/trunk/modules/miscdests/page.miscdests.php
    freepbx-modules/trunk/modules/miscdests/uninstall.sql
    freepbx-modules/trunk/modules/music/functions.inc.php
    freepbx-modules/trunk/modules/music/install.php
    freepbx-modules/trunk/modules/music/module.xml
    freepbx-modules/trunk/modules/music/page.music.php
    freepbx-modules/trunk/modules/paging/functions.inc.php
    freepbx-modules/trunk/modules/paging/install.php
    freepbx-modules/trunk/modules/paging/install.sql
    freepbx-modules/trunk/modules/paging/module.xml
    freepbx-modules/trunk/modules/paging/page.paging.php
    freepbx-modules/trunk/modules/paging/uninstall.sql
    freepbx-modules/trunk/modules/parking/functions.inc.php
    freepbx-modules/trunk/modules/parking/module.xml
    freepbx-modules/trunk/modules/pbdirectory/agi-bin/pbdirectory
    freepbx-modules/trunk/modules/pbdirectory/module.xml
    freepbx-modules/trunk/modules/phonebook/module.xml
    freepbx-modules/trunk/modules/phonebook/page.phonebook.php
    freepbx-modules/trunk/modules/phpagiconf/functions.inc.php
    freepbx-modules/trunk/modules/phpagiconf/module.xml
    freepbx-modules/trunk/modules/phpagiconf/page.phpagiconf.php
    freepbx-modules/trunk/modules/phpinfo/module.xml
    freepbx-modules/trunk/modules/phpinfo/page.phpinfo.php
    freepbx-modules/trunk/modules/pinsets/functions.inc.php
    freepbx-modules/trunk/modules/pinsets/install.php
    freepbx-modules/trunk/modules/pinsets/install.sql
    freepbx-modules/trunk/modules/pinsets/module.xml
    freepbx-modules/trunk/modules/printextensions/module.xml
    freepbx-modules/trunk/modules/printextensions/page.printextensions.php
    freepbx-modules/trunk/modules/queues/functions.inc.php
    freepbx-modules/trunk/modules/queues/module.xml
    freepbx-modules/trunk/modules/queues/page.queues.php
    freepbx-modules/trunk/modules/recordings/functions.inc.php
    freepbx-modules/trunk/modules/recordings/install.php
    freepbx-modules/trunk/modules/recordings/module.xml
    freepbx-modules/trunk/modules/recordings/page.recordings.php
    freepbx-modules/trunk/modules/ringgroups/functions.inc.php
    freepbx-modules/trunk/modules/ringgroups/install.php
    freepbx-modules/trunk/modules/ringgroups/install.sql
    freepbx-modules/trunk/modules/ringgroups/module.xml
    freepbx-modules/trunk/modules/ringgroups/page.ringgroups.php
    freepbx-modules/trunk/modules/speeddial/functions.inc.php
    freepbx-modules/trunk/modules/speeddial/module.xml
    freepbx-modules/trunk/modules/timeconditions/install.sql
    freepbx-modules/trunk/modules/timeconditions/module.xml
    freepbx-modules/trunk/modules/voicemail/functions.inc.php
    freepbx-modules/trunk/modules/voicemail/install.php
    freepbx-modules/trunk/modules/voicemail/module.xml

Modified: freepbx-modules/trunk/modules/announcement/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/announcement/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/announcement/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/announcement/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -2,6 +2,7 @@
 
 function announcement_destinations() {
 	// return an associative array with destination and description
+	$extens = array();
 	foreach (announcement_list() as $row) {
 		$extens[] = array('destination' => 'app-announcement-'.$row[0].',s,1', 'description' => $row[1]);
 	}
@@ -38,7 +39,7 @@
 						$ext->add('app-announcement-'.$row[0], $row[7], '', new ext_goto('s,play'));
 					}
 				} else {
-					$ext->add('app-announcement-'.$row[0], 's', '', new ext_playback($row[2].'|noanswer'));
+					$ext->add('app-announcement-'.$row[0], 's', '', new ext_playback($row[2].',noanswer'));
 				}
 
 				// if repeat_msg enabled then set exten to t to allow for the key to be pressed, otherwise play message and go
@@ -63,7 +64,7 @@
 	$sql = "SELECT announcement_id, description, recording, allow_skip, post_dest, return_ivr, noanswer, repeat_msg FROM announcement ORDER BY description ";
 	$results = $db->getAll($sql);
 	if(DB::IsError($results)) {
-		die($results->getMessage()."<br><br>Error selecting from announcement");	
+		die_freepbx($results->getMessage()."<br><br>Error selecting from announcement");	
 	}
 	return $results;
 }
@@ -73,7 +74,7 @@
 	$sql = "SELECT announcement_id, description, recording, allow_skip, post_dest, return_ivr, noanswer, repeat_msg FROM announcement WHERE announcement_id = ".addslashes($announcement_id);
 	$row = $db->getRow($sql);
 	if(DB::IsError($row)) {
-		die($row->getMessage()."<br><br>Errpr selecting row from announcement");	
+		die_freepbx($row->getMessage()."<br><br>Errpr selecting row from announcement");	
 	}
 	return $row;
 }
@@ -90,7 +91,7 @@
 		"'".addslashes($repeat_msg)."')";
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getMessage().$sql);
+		die_freepbx($result->getMessage().$sql);
 	}
 }
 
@@ -99,7 +100,7 @@
 	$sql = "DELETE FROM announcement WHERE announcement_id = ".addslashes($announcement_id);
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getMessage().$sql);
+		die_freepbx($result->getMessage().$sql);
 	}
 	
 }
@@ -117,7 +118,7 @@
 		"WHERE announcement_id = ".addslashes($announcement_id);
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getMessage().$sql);
+		die_freepbx($result->getMessage().$sql);
 	}
 }
 

Modified: freepbx-modules/trunk/modules/announcement/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/announcement/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/announcement/install.php (original)
+++ freepbx-modules/trunk/modules/announcement/install.php Mon Apr  7 13:18:05 2008
@@ -16,7 +16,7 @@
 )";
 $check = $db->query($sql);
 if(DB::IsError($check)) {
-	die("Can not create annoucment table");
+	die_freepbx("Can not create annoucment table");
 }
 
 // Version 0.3 adds auto-return to IVR
@@ -26,7 +26,7 @@
 	// add new field
     $sql = "ALTER TABLE announcement ADD return_ivr TINYINT(1) NOT NULL DEFAULT 0;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 }
 
 // Version 0.4 adds auto-return to IVR
@@ -36,7 +36,7 @@
 	// add new field
     $sql = "ALTER TABLE announcement ADD noanswer TINYINT(1) NOT NULL DEFAULT 0;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 }
 
 // Version 0.8 upgrade
@@ -49,7 +49,7 @@
     $sql = "ALTER TABLE announcement CHANGE $repeat repeat_msg VARCHAR( 2 ) NOT NULL DEFAULT '' ;"; 
     $result = $db->query($sql);
     if(DB::IsError($result)) {
-            die($result->getDebugInfo());
+            die_freepbx($result->getDebugInfo());
     }
 }
 
@@ -60,6 +60,26 @@
 	// add new field
     $sql = "ALTER TABLE announcement ADD repeat_msg VARCHAR(2) NOT NULL DEFAULT '';";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 }
+
+$results = array();
+$sql = "SELECT announcement_id, post_dest FROM announcement";
+$results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
+if (!DB::IsError($results)) { // error - table must not be there
+	foreach ($results as $result) {
+		$old_dest  = $result['post_dest'];
+		$announcement_id    = $result['announcement_id'];
+
+		$new_dest = merge_ext_followme(trim($old_dest));
+		if ($new_dest != $old_dest) {
+			$sql = "UPDATE announcement SET post_dest = '$new_dest' WHERE announcement_id = $announcement_id  AND post_dest = '$old_dest'";
+			$results = $db->query($sql);
+			if(DB::IsError($results)) {
+				die_freepbx($results->getMessage());
+			}
+		}
+	}
+}
+
 ?>

Modified: freepbx-modules/trunk/modules/announcement/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/announcement/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/announcement/module.xml (original)
+++ freepbx-modules/trunk/modules/announcement/module.xml Mon Apr  7 13:18:05 2008
@@ -1,8 +1,13 @@
 <module>
 	<rawname>announcement</rawname>
 	<name>Announcements</name>
-	<version>0.8.2</version>
+	<version>0.8.5.2</version>
 	<changelog>
+		*0.8.5.2* #2172 deprecated use of |
+		*0.8.5.1* bump for rc1
+		*0.8.5* fixed some undefined variables
+		*0.8.4* changed freePBX to FreePBX
+		*0.8.3* merge findmefollow/core extension destinations if any
 		*0.8.2* skip the answer/wait(1) if channel is already answered
 		*0.8.1* changed response timeout from 10 to 3 seconds (when used at all)
 		*0.8.0* need to add an i extension, even with m option in bacground, it fails if skip is not enabled
@@ -22,7 +27,6 @@
 	<menuitems>
 		<announcement>Announcements</announcement>
 	</menuitems>
-	<location>release/2.2/announcement-0.8.1.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Announcement</info>
-	<md5sum>46d91d3631249fc50c6f1f9954c4e645</md5sum>
+	<location>release/2.3/announcement-0.8.5.1.tgz</location>
+	<md5sum>c466721479ef3467fecf454d82e7a1cc</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/announcement/page.announcement.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/announcement/page.announcement.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/announcement/page.announcement.php (original)
+++ freepbx-modules/trunk/modules/announcement/page.announcement.php Mon Apr  7 13:18:05 2008
@@ -1,5 +1,5 @@
 <?php 
-/** Announcments module for freePBX 2.2+
+/** Announcments module for FreePBX 2.2+
  * Copyright 2006 Greg MacLellan
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -25,7 +25,7 @@
 $post_dest = isset($_POST['post_dest']) ? $_POST['post_dest'] :  '';
 $repeat_msg = isset($_POST['repeat_msg']) ? $_POST['repeat_msg'] :  '';
 
-if ($_POST['goto0']) {
+if (isset($_POST['goto0']) && $_POST['goto0']) {
 	// 'ringgroup_post_dest'  'ivr_post_dest' or whatever
 	$post_dest = $_POST[ $_POST['goto0'].'0' ];
 }

Modified: freepbx-modules/trunk/modules/asterisk-cli/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/asterisk-cli/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/asterisk-cli/module.xml (original)
+++ freepbx-modules/trunk/modules/asterisk-cli/module.xml Mon Apr  7 13:18:05 2008
@@ -1,20 +1,23 @@
 <module>
 	<rawname>asterisk-cli</rawname>
 	<name>Asterisk CLI</name>
-	<version>1.0</version>
+	<version>1.1.2.1</version>
 	<type>tool</type>
-	<category>System Admin</category>
+	<category>System Administration</category>
 	<menuitems>
 		<cli>Asterisk CLI</cli>
 	</menuitems>
 	<depends>
 		<engine>asterisk</engine>
 	</depends>
-	<location>release//2.2/asterisk-cli-0.001.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-CLI</info>
-	<md5sum>d2f19494379f862545fbc4ac27185580</md5sum>
+	<location>release/2.3/asterisk-cli-1.1.2.1.tgz</location>
+	<md5sum>5bfad012ed96fe9c81b900a17751c25f</md5sum>
 	<changelog>
-*1.0* Fixed security issue, first release in 2.2
-*0.001* Original Release
+		*1.1.2.1* bump for rc1
+		*1.1.2* fix syntax error, extra =
+		*1.1.1* #2070 fix proper use of script tags
+		*1.1* #2006 Fixed display on systems with colored asterisk console
+		*1.0* Fixed security issue, first release in 2.2
+		*0.001* Original Release
 	</changelog>
 </module>

Modified: freepbx-modules/trunk/modules/asterisk-cli/page.cli.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/asterisk-cli/page.cli.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/asterisk-cli/page.cli.php (original)
+++ freepbx-modules/trunk/modules/asterisk-cli/page.cli.php Mon Apr  7 13:18:05 2008
@@ -35,7 +35,7 @@
 	<table>
 		<tr>
 			<td class="label" align="right"><?php echo _("Command:")?></td>
-			<td class="type"><input name="txtCommand" type="text" size="70" value="<?=htmlspecialchars($txtCommand);?>"></td>
+			<td class="type"><input name="txtCommand" type="text" size="70" value="<?php htmlspecialchars($txtCommand);?>"></td>
 		</tr>
 		
 		<tr>
@@ -67,7 +67,7 @@
 	putenv("SCRIPT_FILENAME=" . strtok(stripslashes($txtCommand), " "));  /* PHP scripts */
 	$badchars = array("'", "`", "\\", ";", "\""); // Strip off any nasty chars.
 	$fixedcmd = str_replace($badchars, "", $txtCommand);
-	$ph = popen(stripslashes("asterisk -rx \"$fixedcmd\""), "r" );
+	$ph = popen(stripslashes("asterisk -nrx \"$fixedcmd\""), "r" );
 	while ($line = fgets($ph))
 		echo htmlspecialchars($line);
 	pclose($ph);
@@ -76,4 +76,3 @@
 
 ?>
 
-</div>

Modified: freepbx-modules/trunk/modules/asteriskinfo/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/asteriskinfo/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/asteriskinfo/module.xml (original)
+++ freepbx-modules/trunk/modules/asteriskinfo/module.xml Mon Apr  7 13:18:05 2008
@@ -1,7 +1,7 @@
 <module>
 	<rawname>asteriskinfo</rawname>
 	<name>Asterisk Info</name>
-	<version>0.2.0</version>
+	<version>0.3.0.1</version>
 	<type>tool</type>
 	<category>System Administration</category>
 	<description>
@@ -14,10 +14,11 @@
 		<engine>asterisk</engine>
 	</depends>
 	<changelog>
+		*0.3.0.1* bump for rc1
+		*0.3.0* #2187 Fix for Asterisk 1.4
+		*0.2.0* Add depends asterisk xml tag, proper error checking for manager connection, center table titles
 		*0.1.0* Initial release
-		*0.2.0* Add depends asterisk xml tag, proper error checking for manager connection, center table titles
 	</changelog>
-	<location>release/2.2/asteriskinfo-0.1.0.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-AsteriskInfo</info>
-	<md5sum>7af97204fc1de74269bea8de1b62b3df</md5sum>
+	<location>release/2.3/asteriskinfo-0.3.0.1.tgz</location>
+	<md5sum>c62e2db14ebaa1fcac7a29f6a999145c</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/asteriskinfo/page.asteriskinfo.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/asteriskinfo/page.asteriskinfo.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/asteriskinfo/page.asteriskinfo.php (original)
+++ freepbx-modules/trunk/modules/asteriskinfo/page.asteriskinfo.php Mon Apr  7 13:18:05 2008
@@ -85,6 +85,24 @@
 			$astver=$matches[1];
 		}
 	} 
+}
+
+if(preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $astver, $matches)){
+	$astver_major=$matches[1];
+	$astver_minor=$matches[2];
+}else{
+	$astver_major = 1;
+	$astver_minor = 2;
+}
+
+if ($astver_major == 1 && $astver_minor >= 4) {
+	$arr_all["Uptime"]="core show uptime";
+	$arr_all["Active Channel(s)"]="core show channels";
+	$arr_all["Subscribe/Notify"]="core show hints";
+	$arr_all["Voicemail users"]="voicemail show users";
+	$arr_channels["Active Channel(s)"]="core show channels";
+	$arr_subscriptions["Subscribe/Notify"]="core show hints";
+	$arr_voicemail["Voicemail users"]="voicemail show users";
 }
 
 ?>
@@ -236,6 +254,7 @@
 }
 
 function getPeer($peer, $channelType = NULL){
+	global $astver_major, $astver_minor;
 	if(count($peer) > 1){	
 		if($channelType == NULL || $channelType == 'SIP'){
 			$sipPeer = $peer;
@@ -244,8 +263,13 @@
 			$sipPeerInfo_string = $sipPeer[$sipPeer_count -2];
 			$sipPeerInfo_arr2 = explode('[',$sipPeerInfo_string);
 			$sipPeerInfo_arr3 = explode(' ',$sipPeerInfo_arr2[1]);
-			$sipPeerInfo_arr['online'] = $sipPeerInfo_arr3[0];
-			$sipPeerInfo_arr['offline'] = $sipPeerInfo_arr3[3];
+			if($astver_major == 1 && $astver_minor >= 4){
+				$sipPeerInfo_arr['online'] = $sipPeerInfo_arr3[1] + $sipPeerInfo_arr3[6];
+				$sipPeerInfo_arr['offline'] = $sipPeerInfo_arr3[3] + $sipPeerInfo_arr3[8];
+			}else{
+				$sipPeerInfo_arr['online'] = $sipPeerInfo_arr3[0];
+				$sipPeerInfo_arr['offline'] = $sipPeerInfo_arr3[3];
+			}
 			return $sipPeerInfo_arr;
 			
 		}elseif($channelType == 'IAX2'){

Modified: freepbx-modules/trunk/modules/backup/bin/ampbackup.pl
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/backup/bin/ampbackup.pl?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/backup/bin/ampbackup.pl (original)
+++ freepbx-modules/trunk/modules/backup/bin/ampbackup.pl Mon Apr  7 13:18:05 2008
@@ -60,6 +60,22 @@
 $User_Preferences{"AMPDBPASS"}  = "amp109";
 $User_Preferences{"AMPDBNAME"}  = "asterisk";
 $User_Preferences{"AMPWEBROOT"} = "/var/www/html";
+$User_Preferences{"ASTETCDIR"} = "/etc/asterisk";
+
+$User_Preferences{"AMPPROVROOT"} = "";
+$User_Preferences{"AMPPROVEXCLUDE"} = "";
+
+$User_Preferences{"FTPBACKUP"} = "";
+$User_Preferences{"FTPUSER"} = "";
+$User_Preferences{"FTPPASSWORD"} = "";
+$User_Preferences{"FTPSUBDIR"} = "";
+$User_Preferences{"FTPSERVER"} = "";
+
+$User_Preferences{"SSHBACKUP"} = "";
+$User_Preferences{"SSHUSER"} = "";
+$User_Preferences{"SSHRSAKEY"} = "";
+$User_Preferences{"SSHSUBDIR"} = "";
+$User_Preferences{"SSHSERVER"} = "";
 
 open(FILE, "/etc/amportal.conf") || die "Failed to open amportal.conf\n";
 while (<FILE>) {
@@ -73,7 +89,7 @@
 }
 close(FILE);
 
-open(FILE, "/etc/asterisk/asterisk.conf") || die "Failed to open asterisk.conf\n";
+open(FILE, $User_Preferences{"ASTETCDIR"}."/asterisk.conf") || die "Failed to open asterisk.conf\n";
 while (<FILE>) {
 	chomp;
 	s/\s//g;	# No spaces, anywhere.
@@ -84,6 +100,8 @@
 		$ast{$1} = $2;
 	}
 }
+
+$backupdir = $ast{'astvarlibdir'}."/backups";
 
 # username to connect to the database
 $username = $User_Preferences{"AMPDBUSER"} ;
@@ -96,6 +114,11 @@
 # the WEB ROOT directory 
 $webroot = $User_Preferences{"AMPWEBROOT"};
 
+# Provisioning root(s) and exclude list, if phone configuratoins should be backed up
+#
+$provroot = $User_Preferences{"AMPPROVROOT"};
+$excludefile = $User_Preferences{"AMPPROVEXCLUDE"};
+
 # If and where to send the backup file once created (still left on local machine as well)
 #
 $ftpbackup = uc $User_Preferences{"FTPBACKUP"};
@@ -103,6 +126,12 @@
 $ftppassword = $User_Preferences{"FTPPASSWORD"};
 $ftpsubdir = $User_Preferences{"FTPSUBDIR"};
 $ftpserver = $User_Preferences{"FTPSERVER"};
+
+$sshbackup = uc $User_Preferences{"SSHBACKUP"};
+$sshuser = $User_Preferences{"SSHUSER"};
+$sshrsakey = $User_Preferences{"SSHRSAKEY"};
+$sshsubdir = $User_Preferences{"SSHSUBDIR"};
+$sshserver = $User_Preferences{"SSHSERVER"};
 
 ################### END OF CONFIGURATION #######################
 my $now = localtime time;
@@ -111,7 +140,6 @@
 $mon +=1;
 #my $Stamp="$year$mon$mday.$hour.$min.$sec";
 my $Stamp=sprintf "%04d%02d%02d.%02d.%02d.%02d",$year,$mon,$mday,$hour,$min,$sec;
-
 
 if (scalar @ARGV > 1)
 {
@@ -152,8 +180,6 @@
 		#print "$Backup_Name $Backup_Voicemail $Backup_Recordings $Backup_Configurations $Backup_CDR $Backup_FOP\n";
 	}
 }
-#print "$Backup_Name $Backup_Voicemail $Backup_Recordings $Backup_Configurations $Backup_CDR $Backup_FOP\n";
-
 
 	system ("/bin/rm -rf /tmp/ampbackups.$Stamp > /dev/null  2>&1");
 	system ("/bin/mkdir /tmp/ampbackups.$Stamp > /dev/null  2>&1");
@@ -166,6 +192,15 @@
 	if ( $Backup_Configurations eq "yes" ){
 		system ($ast{'astvarlibdir'}."/bin/dumpastdb.php $Stamp > /dev/null");
 		system ("/bin/tar -Pcz -f /tmp/ampbackups.$Stamp/configurations.tar.gz ".$ast{'astvarlibdir'}."/agi-bin/ ".$ast{'astvarlibdir'}."/bin/ /etc/asterisk $webroot/admin /etc/amportal.conf /tmp/ampbackups.$Stamp/astdb.dump ");
+
+		if ($provroot ne "") {
+			$excludearg = "";
+			if (-r $excludefile) {
+				$excludearg = "--exclude-from $excludefile ";
+			}
+			system ("/bin/tar -Pcz $excludearg -f /tmp/ampbackups.$Stamp/phoneconfig.tar.gz $provroot ");
+		}
+
 		system ("mysqldump --add-drop-table -h $hostname -u $username -p$password --database $database > /tmp/ampbackups.$Stamp/asterisk.sql");
 	}
 	if ( $Backup_CDR eq "yes" ){
@@ -175,8 +210,8 @@
 	if ( $Backup_FOP eq "yes" ){
 		system ("/bin/tar -Pcz -f /tmp/ampbackups.$Stamp/fop.tar.gz $webroot/panel");
 	}
-	system ("/bin/mkdir -p '/var/lib/asterisk/backups/$Backup_Name' > /dev/null  2>&1");
-	system ("/bin/tar -Pcz -f '/var/lib/asterisk/backups/$Backup_Name/$Stamp.tar.gz' /tmp/ampbackups.$Stamp");
+	system ("/bin/mkdir -p '$backupdir/$Backup_Name' > /dev/null  2>&1");
+	system ("/bin/tar -Pcz -f '$backupdir/$Backup_Name/$Stamp.tar.gz' /tmp/ampbackups.$Stamp");
 	system ("/bin/rm -rf /tmp/ampbackups.$Stamp > /dev/null  2>&1");
 #
 #
@@ -187,26 +222,33 @@
 #             root leave the file around and asterisk can't overwrite it.
 #	      Note - the hardcoded full backup that cron does will overwrite each day at destination.
 #
-if ( $ftpbackup ne "YES" ) {
-	exit
-}
-
-open(FILE, ">$ftpfile") || die "Failed to open $ftpfile\n";
+if ( $ftpbackup eq "YES" ) {
+	open(FILE, ">$ftpfile") || die "Failed to open $ftpfile\n";
  
-        printf FILE "user $ftpuser $ftppassword \n";
-        printf FILE "binary\n";
-	if ( $ftpsubdir ne "" ) {
-        	printf FILE "cd $ftpsubdir \n";
-	}
-        printf FILE "lcd /var/lib/asterisk/backups/$Backup_Name/\n";
-        printf FILE "put $Stamp.tar.gz\n";
-        printf FILE "bye\n";
-        close(FILE);
+		printf FILE "user $ftpuser $ftppassword \n";
+		printf FILE "binary\n";
+			if ( $ftpsubdir ne "" ) {
+				printf FILE "cd $ftpsubdir \n";
+			}
+			printf FILE "lcd $backupdir/$Backup_Name/\n";
+			printf FILE "put $Stamp.tar.gz\n";
+			printf FILE "bye\n";
+			close(FILE);
  
-        system ("ftp -n $ftpserver < $ftpfile > /dev/null  2>&1");
+			system ("ftp -n $ftpserver < $ftpfile > /dev/null  2>&1");
  
-        #system ("/bin/rm -rf /tmp/ftp2cabana > /dev/null  2>&1");
-
-
+			#system ("/bin/rm -rf /tmp/ftp2cabana > /dev/null  2>&1");
+}
+
+if ( ($sshbackup eq "YES") && ($sshrsakey ne "") && ($sshserver ne "") ) {
+
+	if ($sshuser eq "") {
+		$sshuser = system("whoami");
+	}
+	if ($sshsubdir ne "") {
+		system("/usr/bin/ssh -o StrictHostKeyChecking=no -i $sshrsakey $sshuser\@$sshserver mkdir -p $sshsubdir");
+	}
+	system("/usr/bin/scp -o StrictHostKeyChecking=no -i $sshrsakey $backupdir/$Backup_Name/$Stamp.tar.gz $sshuser\@$sshserver:$sshsubdir");
+}
 
 exit 0;

Modified: freepbx-modules/trunk/modules/backup/bin/dumpastdb.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/backup/bin/dumpastdb.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/backup/bin/dumpastdb.php (original)
+++ freepbx-modules/trunk/modules/backup/bin/dumpastdb.php Mon Apr  7 13:18:05 2008
@@ -1,5 +1,5 @@
 #!/usr/bin/env php
-<?
+<?php
 // No use outputting anything, as env forces php headers to appear. Sigh.
 
 global $argv;

Modified: freepbx-modules/trunk/modules/backup/bin/restoreastdb.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/backup/bin/restoreastdb.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/backup/bin/restoreastdb.php (original)
+++ freepbx-modules/trunk/modules/backup/bin/restoreastdb.php Mon Apr  7 13:18:05 2008
@@ -1,5 +1,5 @@
 #!/usr/bin/env php
-<?
+<?php
 // No use outputting anything, as env forces php headers to appear. Sigh.
 
 global $argv;

Modified: freepbx-modules/trunk/modules/backup/bin/retrieve_backup_cron_from_mysql.pl
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/backup/bin/retrieve_backup_cron_from_mysql.pl?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/backup/bin/retrieve_backup_cron_from_mysql.pl (original)
+++ freepbx-modules/trunk/modules/backup/bin/retrieve_backup_cron_from_mysql.pl Mon Apr  7 13:18:05 2008
@@ -30,10 +30,16 @@
 $table_name = "Backup";
 # the path to the extensions.conf file
 # WARNING: this file will be substituted by the output of this program
-$Backup_cron = "/etc/asterisk/backup.conf";
 
 # cool hack by Julien BLACHE <jblache at debian.org>
 $ampconf = parse_amportal_conf( "/etc/amportal.conf" );
+
+$astetcdir = "/etc/asterisk";
+
+if (defined $ampconf->{'ASTETCDIR'}) {
+	$astetcdir = $ampconf->{'ASTETCDIR'};
+}
+$Backup_cron = "$astetcdir/backup.conf";
 
 ################### END OF CONFIGURATION #######################
 

Added: freepbx-modules/trunk/modules/backup/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/backup/install.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/backup/install.php (added)
+++ freepbx-modules/trunk/modules/backup/install.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,32 @@
+<?php
+
+global $db;
+global $amp_conf;
+
+$autoincrement = (($amp_conf["AMPDBENGINE"] == "sqlite") || ($amp_conf["AMPDBENGINE"] == "sqlite3")) ? "AUTOINCREMENT":"AUTO_INCREMENT";
+
+$sql = "
+CREATE TABLE IF NOT EXISTS Backup (
+	  Name varchar(50) default NULL,
+	  Voicemail varchar(50) default NULL,
+	  Recordings varchar(50) default NULL,
+	  Configurations varchar(50) default NULL,
+	  CDR varchar(55) default NULL,
+	  FOP varchar(50) default NULL,
+	  Minutes varchar(50) default NULL,
+	  Hours varchar(50) default NULL,
+	  Days varchar(50) default NULL,
+	  Months varchar(50) default NULL,
+	  Weekdays varchar(50) default NULL,
+	  Command varchar(200) default NULL,
+	  Method varchar(50) default NULL,
+	  ID int(11) NOT NULL $autoincrement,
+	  PRIMARY KEY  (ID)
+);";
+
+$check = $db->query($sql);
+if(DB::IsError($check)) {
+	die_freepbx("Can not create Backup table");
+}
+
+?>

Modified: freepbx-modules/trunk/modules/backup/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/backup/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/backup/module.xml (original)
+++ freepbx-modules/trunk/modules/backup/module.xml Mon Apr  7 13:18:05 2008
@@ -1,7 +1,7 @@
 <module>
 	<rawname>backup</rawname>
 	<name>Backup &amp; Restore</name>
-	<version>2.1.1.3</version>
+	<version>2.1.4.8</version>
 	<type>tool</type>
 	<category>System Administration</category>
 	<menuitems>
@@ -11,19 +11,26 @@
 		<module>core</module>
 	</depends>
 	<changelog>
-	*2.1.1.3* #2323 allow remote MySQL database
-	*2.1.1.2* #2267 restoreadtb restore values with spaces
-	*2.1.1.1* #2231 restore astdb as part of configuration restore choice
-	*2.1.1* Remove core_users2astdb and core_devices2astdb, it isn't needed and corrupts resotred ampuser info
-	*2.1* Actually, really, restore ASTDB now. Finally. Also add redirect_standard to avoid problems with TRBoE.
-	*2.0.4* Add he_IL translation
-	*2.0.3* don't have BLKVM and FM astdb trees, which shouldn't be left around anyhow
-	*2.0.2* fixed restore ALL to get it to actually work
-	*2.0.1* supplied defaults and fixed bug is weekdays schedule_functions.php - #1279
-	*2.0* Now backs up and restores astdb, which was causing problems with phone configurations.
-	*1.2* Potential fix for restore issues, clean up some warnings
+		*2.1.4.8* #2323 allow remote MySQL database
+		*2.1.4.7* #2267 restoreadtb restore values with spaces
+		*2.1.4.6* bump for rc1 (and really chcek in uninstall fix)
+		*2.1.4.5* fixed syntax error in uninstall script
+		*2.1.4.4* #2231 restore astdb as part of configuration restore choice
+		*2.1.4.3* #2070 fix proper use of script tags
+		*2.1.4.2* #1866 removed some hard coded paths
+		*2.1.4.1* changed freePBX to FreePBX
+		*2.1.4* modified install script to create table if NOT EXISTS to avoid errors
+		*2.1.3* #1992: move create/remove schema for Backup into module away from core
+		*2.1.2* Add ability to scp backups to a server, add optional provisioning directory that can be backed up (no restore ability)
+		*2.1.1* Remove core_users2astdb and core_devices2astdb, it isn't needed and corrupts resotred ampuser info
+		*2.1* Actually, really, restore ASTDB now. Finally. Also add redirect_standard to avoid problems with TRBoE.
+		*2.0.4* Add he_IL translation
+		*2.0.3* don't have BLKVM and FM astdb trees, which shouldn't be left around anyhow
+		*2.0.2* fixed restore ALL to get it to actually work
+		*2.0.1* supplied defaults and fixed bug is weekdays schedule_functions.php - #1279
+		*2.0* Now backs up and restores astdb, which was causing problems with phone configurations.
+		*1.2* Potential fix for restore issues, clean up some warnings
 	</changelog>
-	<location>release/2.2/backup-2.1.1.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-BackupRestore</info>
-	<md5sum>35a2fddab1e20e79a76f514a9d1716f1</md5sum>
+	<location>release/2.3/backup-2.1.4.7.tgz</location>
+	<md5sum>24d33b6ee299d6c184d8237f6cae476b</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/backup/schedule_functions.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/backup/schedule_functions.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/backup/schedule_functions.php (original)
+++ freepbx-modules/trunk/modules/backup/schedule_functions.php Mon Apr  7 13:18:05 2008
@@ -39,11 +39,11 @@
                 echo "<br>";
                 $tar_string="tar tfz \"$dir\" | cut -d'/' -f4";
                 exec($tar_string,$restore_files,$error);
-                echo "<li><a class=\"info\" href=\"javascript:decision('Are you sure you want to restore this COMPLETE file set?\nDoing so will permanently over-write all freePBX and Asterisk files\n You will loose all Your Call Detail Records and any Voicemail that was recorded between the BACKUP DATE and NOW.','config.php?type=$type&display=$display&action=restored&dir=$dir&filetype=ALL&file=$file')\">";
+                echo "<li><a class=\"info\" href=\"javascript:decision('Are you sure you want to restore this COMPLETE file set?\n Doing so will permanently over-write all FreePBX and Asterisk files\n You will loose all Your Call Detail Records and any Voicemail that was recorded between the BACKUP DATE and NOW.','config.php?type=$type&display=$display&action=restored&dir=$dir&filetype=ALL&file=$file')\">";
 		echo _("Restore Entire Backup Set"); echo "<span>"; echo _("Restore your Complete Backup set overwriting all files."); echo "</span></a><br></li>";
                 echo "<br>";
                 if (array_search('voicemail.tar.gz',$restore_files)){
-                        echo "<li><a class=\"info\" href=\"javascript:decision('Are you sure you want to Restore this file set?\nDoing so will permanently delete any new voicemail you have in your mailbox\n since this backup on $file?','config.php?type=$type&display=$display&action=restored&dir=$dir&filetype=VoiceMail&file=$file')\">";
+                        echo "<li><a class=\"info\" href=\"javascript:decision('Are you sure you want to Restore this file set?\n Doing so will permanently delete any new voicemail you have in your mailbox\n since this backup on $file?','config.php?type=$type&display=$display&action=restored&dir=$dir&filetype=VoiceMail&file=$file')\">";
 			echo _("Restore VoiceMail Files");echo "<span>"; echo _("Restore your Voicemail files from this backup set.  NOTE! This will delete any voicemail currently in the voicemail boxes.");
 			echo "</span></a><br></li>";
                         echo "<br>";
@@ -55,17 +55,17 @@
                         echo "<br>";
                 }
                 if (array_search('configurations.tar.gz',$restore_files)){
-                        echo "<li><a class=\"info\" href=\"javascript:decision('Are you sure you want to Restore this File Set\nDoing so will Permanently Over-Write all AMP and Asterisk Files?','config.php?type=$type&display=$display&action=restored&dir=$dir&filetype=Configurations&file=$file')\">";
+                        echo "<li><a class=\"info\" href=\"javascript:decision('Are you sure you want to Restore this File Set\n Doing so will Permanently Over-Write all AMP and Asterisk Files?','config.php?type=$type&display=$display&action=restored&dir=$dir&filetype=Configurations&file=$file')\">";
 			echo _("Restore System Configuration"); echo "<span>"; echo _("Restore your system configuration from this backup set.  NOTE! This will OVERWRITE any System changes you have made since this backup... ALL Itemes will be reset to what they were at the time of this backup set.."); echo "</span></a><br></li>";
                         echo "<br>";
                 }
                 if (array_search('fop.tar.gz',$restore_files)){
-                        echo "<li><a class=\"info\" href=\"javascript:decision('Are you sure you want to Restore the Operator Panel Files\nDoing so will Permanently Over-Write all Operator Panel Files?','config.php?type=$type&display=$display&action=restored&dir=$dir&filetype=FOP&file=$file')\">";
+                        echo "<li><a class=\"info\" href=\"javascript:decision('Are you sure you want to Restore the Operator Panel Files\n Doing so will Permanently Over-Write all Operator Panel Files?','config.php?type=$type&display=$display&action=restored&dir=$dir&filetype=FOP&file=$file')\">";
 			echo _("Restore Operator Panel"); echo "<span>"; echo _("Restore the Operator Panel from this backup set.  NOTE! This will OVERWRITE any Operator Panel Changes you have made since this backup... ALL Itemes will be reset to what they were at the time of this backup set.."); echo "</span></a><br></li>";
                         echo "<br>";
                 }
                 if (array_search('cdr.tar.gz',$restore_files)){
-                        echo "<li><a class=\"info\" href=\"javascript:decision('Are you sure you want to Restore the CALL DETAIL FILES \nDoing so will Permanently DELETE  all CALL RECORDS.?','config.php?type=$type&display=$display&action=restored&dir=$dir&filetype=CDR&file=$file')\">";
+                        echo "<li><a class=\"info\" href=\"javascript:decision('Are you sure you want to Restore the CALL DETAIL FILES\n Doing so will Permanently DELETE  all CALL RECORDS.?','config.php?type=$type&display=$display&action=restored&dir=$dir&filetype=CDR&file=$file')\">";
 			echo _("Restore Call Detail Report"); echo "<span>"; echo _("Restore the Call Detail Records from this backup set.  NOTE! This will DELETE ALL CALL RECORDS that have been saved since this backup set.."); echo "</span></a><br></li>";
                         echo "<br>";
                 }
@@ -173,7 +173,7 @@
 	$sql = "DELETE FROM Backup  WHERE ID = '$ID'";
         $result = $db->query($sql);
         if(DB::IsError($result)) {
-                die($result->getMessage());
+                die_freepbx($result->getMessage());
         }
 	$Cron_Script=$asterisk_conf['astvarlibdir']."/bin/retrieve_backup_cron_from_mysql.pl";
 	exec($Cron_Script);
@@ -204,7 +204,7 @@
         $sql .= "'".$Backup_Parms[1]."');";
         $result = $db->query($sql);
         if(DB::IsError($result)) {
-                die($result->getMessage().'<hr>'.$sql);
+                die_freepbx($result->getMessage().'<hr>'.$sql);
         }
 	$Cron_Script=$asterisk_conf['astvarlibdir']."/bin/retrieve_backup_cron_from_mysql.pl";
 	exec($Cron_Script);

Added: freepbx-modules/trunk/modules/backup/uninstall.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/backup/uninstall.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/backup/uninstall.php (added)
+++ freepbx-modules/trunk/modules/backup/uninstall.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,14 @@
+<?php
+
+global $db;
+global $asterisk_conf;
+$sql = "DELETE FROM Backup";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	die_freepbx($result->getMessage());
+}
+$Cron_Script=$asterisk_conf['astvarlibdir']."/bin/retrieve_backup_cron_from_mysql.pl";
+exec($Cron_Script);
+sql('DROP TABLE Backup');
+
+?>

Modified: freepbx-modules/trunk/modules/blacklist/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/blacklist/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/blacklist/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/blacklist/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -62,8 +62,7 @@
 	$ext->add($id, $c, '', new ext_saydigits('${blacknr}'));
 	$ext->add($id, $c, '', new ext_Playback('if-correct-press&digits/1'));
 	$ext->add($id, $c, '', new ext_noop('Waiting for input'));
-	//$ext->add($id, $c, 'end', new ext_waitexten(60));
-	$ext->add($id, $c, 'end', new extension('WaitExten(60)'));
+	$ext->add($id, $c, 'end', new ext_waitexten(60));
 	$ext->add($id, $c, '', new ext_Playback('sorry-youre-having-problems&goodbye'));
 	$c = "1";
 	$ext->add($id, $c, '', new ext_set('DB(blacklist/${blacknr})', 1));
@@ -88,8 +87,7 @@
 	$ext->add($id, $c, '', new ext_saydigits('${blacknr}'));
 	$ext->add($id, $c, '', new ext_Playback('if-correct-press&digits/1'));
 	$ext->add($id, $c, '', new ext_noop('Waiting for input'));
-	//$ext->add($id, $c, 'end', new ext_waitexten(60));
-	$ext->add($id, $c, 'end', new extension('WaitExten(60)'));
+	$ext->add($id, $c, 'end', new ext_waitexten(60));
 	$ext->add($id, $c, '', new ext_Playback('sorry-youre-having-problems&goodbye'));
 	$c = "1";
  	$ext->add($id, $c, '', new ext_dbdel('blacklist/${blacknr}'));
@@ -118,8 +116,7 @@
 	$ext->add($id, $c, 'noinfo', new ext_playback('unidentified-no-callback'));
 	$ext->add($id, $c, '', new ext_hangup);
 	$ext->add($id, $c, '', new ext_noop('Waiting for input'));
-	//$ext->add($id, $c, 'end', new ext_waitexten(60));
-	$ext->add($id, $c, 'end', new extension('WaitExten(60)')); // n,VoiceMailMain(${VMCONTEXT})
+	$ext->add($id, $c, 'end', new ext_waitexten(60));
 	$ext->add($id, $c, '', new ext_Playback('sorry-youre-having-problems&goodbye'));
 	$c = "1";
 	$ext->add($id, $c, '', new ext_set('DB(blacklist/${lastcaller})', 1));

Modified: freepbx-modules/trunk/modules/blacklist/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/blacklist/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/blacklist/module.xml (original)
+++ freepbx-modules/trunk/modules/blacklist/module.xml Mon Apr  7 13:18:05 2008
@@ -1,21 +1,24 @@
 <module>
 	<rawname>blacklist</rawname>
 	<name>Blacklist</name>
-	<version>1.1.3.2</version>
+	<version>1.1.3.6</version>
 	<type>setup</type>
-	<category>CID &amp; Number Management</category>
+	<category>Inbound Call Control</category>
 	<menuitems>
-		<blacklist>Blacklist</blacklist>
+		<blacklist needsenginedb="yes">Blacklist</blacklist>
 	</menuitems>
 	<changelog>
-	*1.1.3.2* #2107 some more ext_watiexten got missed, fixed
-	*1.1.3.1* #2107 replaced ext_waitexten with explicit extension class
-	*1.1.3* #2061 fixed to work with Asterisk 1.4 (wait for confirmation of 1)
-	*1.1.2* #1638 remove duplicate of zapateller instruction
-	*1.1.1* Add he_IL translation
-	*1.1* First 2.2 release. Fix minor warnings.
+		*1.1.3.6* #2455 allow + and other valid dial digits
+		*1.1.3.5* changed categories
+		*1.1.3.4* bump for rc1
+		*1.1.3.3* added xml attribute needsenginedb
+		*1.1.3.2* #2070 syntax fix from below
+		*1.1.3.1* #2070 fix proper use of script tags
+		*1.1.3* #2061 fixed to work with Asterisk 1.4 (wait for confirmation of 1)
+		*1.1.2* #1638 remove duplicate of zapateller instruction
+		*1.1.1* Add he_IL translation
+		*1.1* First 2.2 release. Fix minor warnings.
 	</changelog>
-	<location>release/2.2/blacklist-1.1.3.1.tgz</location>
-	<info>http://freepbx.org/wiki/AsteriskBlacklist</info>
-	<md5sum>364c37e46158490a4594e9b1d9db976d</md5sum>
+	<location>release/2.3/blacklist-1.1.3.5.tgz</location>
+	<md5sum>cf4242b07391e0f6c4557ac7ed16557d</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/blacklist/page.blacklist.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/blacklist/page.blacklist.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/blacklist/page.blacklist.php (original)
+++ freepbx-modules/trunk/modules/blacklist/page.blacklist.php Mon Apr  7 13:18:05 2008
@@ -63,7 +63,7 @@
 	</tr>
 
 	<tr>
-		<td><b><?=_("Number")?></b></td>
+		<td><b><?php _("Number") ?></b></td>
 		<td>&nbsp;</td>
 		<td>&nbsp;</td>
 	</tr>
@@ -105,16 +105,32 @@
 		<td colspan="2"><br><h6><input name="submit" type="submit" value="<?php echo _("Submit Changes")?>"></h6></td>
 	</tr>
 	</table>
-
 <script language="javascript">
 <!--
 
 var theForm = document.edit;
 theForm.number.focus();
 
+function isDialDigitsPlus(s)
+{
+	var i;
+
+	if (isEmpty(s)) {
+		return false;
+	}
+
+	for (i = 0; i < s.length; i++) {
+		var c = s.charAt(i);
+
+		if (!isDialDigitChar(c) && (c != "+")) return false;
+	}
+	return true;
+}
+
+
 function edit_onsubmit() {
 	defaultEmptyOK = false;
-        if (!isInteger(theForm.number.value))
+        if (!isDialDigitsPlus(theForm.number.value))
                 return warnInvalid(theForm.number, "Please enter a valid Number");
 	return true;
 }

Added: freepbx-modules/trunk/modules/callback/bin/callback
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/callback/bin/callback?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/callback/bin/callback (added)
+++ freepbx-modules/trunk/modules/callback/bin/callback Mon Apr  7 13:18:05 2008
@@ -1,0 +1,140 @@
+#!/usr/bin/php -q
+<?php
+/*
+This Callback script takes 3 arguments:
+1- number to dial
+2- context.exten.priority to dump number into
+3- time in seconds to sleep before calling back
+
+eg: callback 14032448089 ext-meetme.200.1
+*/
+
+//Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+?>
+
+<?php
+define("AMP_CONF", "/etc/amportal.conf");
+
+//sleep(10);
+
+/**************************************************************/
+
+// from  ben-php dot net at efros dot com   at  php.net/install.unix.commandline
+if (version_compare(phpversion(),'4.3.0','<') || !defined("STDIN")) {
+	define('STDIN',fopen("php://stdin","r"));
+	define('STDOUT',fopen("php://stdout","r"));
+	define('STDERR',fopen("php://stderr","r"));
+	register_shutdown_function( create_function( '' , 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;' ) );
+}
+
+// **** Make sure we have PEAR's GetOpts.php, and include it
+
+outn("Checking for PEAR Console::Getopt..");
+if (! @ include("Console/Getopt.php")) {
+	out("FAILED");
+	fatal("PEAR must be installed (requires Console/Getopt.php). Include path: ".ini_get("include_path"));
+}
+out("OK");
+
+
+outn("Reading ".AMP_CONF."..");
+$amp_conf = parse_amportal_conf(AMP_CONF);
+if (count($amp_conf) == 0) {
+	fatal("FAILED");
+}
+out("OK");
+
+// include manager functions
+include $amp_conf['AMPWEBROOT'].'/admin/common/php-asmanager.php';
+
+// **** Parse out command-line args
+// context, extension, and number of voicemails
+out("Getting passed arguments:");
+$con  = new Console_Getopt;
+$args = $con->readPHPArgv();
+array_shift($args);
+//system("echo \"".$args[0].substr($args[1],0,strpos($args[1],"@")).$args[2]."\" > on.txt"); ;
+print_r($args);
+
+$callback_number = $args[0];
+$callback_destination = $args[1];
+$pause_seconds = $args[2];
+
+if($pause_seconds)
+	sleep($pause_seconds);
+	
+// figure out context, exten, priority
+$dest = explode(".",$callback_destination);
+$callback_context = $dest[0];
+$callback_exten = $dest[1];
+$callback_priority = $dest[2];
+
+//define the args for Originate
+$channel = "Local/".$callback_number."@from-internal";
+//$channel = "zap/g0/".$uservm[$vmcontext][$vmextension]['options']['callme'];
+$exten = $callback_exten;
+$context = $callback_context;
+$priority = $callback_priority;
+$timeout = "15000";
+$callerid = "Callback";
+$variable = "";
+$account = "";
+$application = "";
+$data = "";
+
+//connect to manager and dial
+$astman = new AGI_AsteriskManager();
+if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {
+	$astman->Originate($channel, $exten, $context, $priority, $timeout, $callerid, $variable, $account, $application, $data);
+} else {
+	fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
+}
+$astman->disconnect();
+
+
+
+
+
+
+
+
+
+
+function parse_amportal_conf($filename) {
+	$file = file($filename);
+	foreach ($file as $line) {
+		if (preg_match("/^\s*([a-zA-Z0-9]+)\s*=\s*(.*)\s*([;#].*)?/",$line,$matches)) { 
+			$conf[ $matches[1] ] = $matches[2];
+		}
+	}
+	return $conf;
+}
+
+function out($text) {
+	echo $text."\n";
+}
+
+function outn($text) {
+	echo $text;
+}
+
+function error($text) {
+	echo "[ERROR] ".$text."\n";
+}
+
+function fatal($text) {
+	echo "[FATAL] ".$text."\n";
+	exit(1);
+}
+
+?>

Propchange: freepbx-modules/trunk/modules/callback/bin/callback
------------------------------------------------------------------------------
    svn:executable = *

Modified: freepbx-modules/trunk/modules/callback/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/callback/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/callback/install.php (original)
+++ freepbx-modules/trunk/modules/callback/install.php Mon Apr  7 13:18:05 2008
@@ -1,6 +1,24 @@
 <?php
 
 global $db;
+global $amp_conf;
+
+$autoincrement = ($amp_conf["AMPDBENGINE"] == "sqlite3") ? "AUTOINCREMENT":"AUTO_INCREMENT";
+
+$sql = "CREATE TABLE IF NOT EXISTS callback (
+	callback_id INTEGER NOT NULL PRIMARY KEY $autoincrement,
+	description VARCHAR( 50 ) ,
+	callbacknum VARCHAR( 100 ) ,
+	destination VARCHAR( 50 ) ,
+	sleep INTEGER,
+	deptname VARCHAR( 50 )
+);";
+
+$check = $db->query($sql);
+if (DB::IsError($check)) {
+	die_freepbx( "Can not create `callback` table: " . $check->getMessage() .  "\n");
+}
+
 
 // Version 1.1 upgrade - add sleep time.
 $sql = "SELECT sleep FROM callback";
@@ -10,4 +28,23 @@
 	sql('ALTER TABLE callback ADD COLUMN sleep INT DEFAULT 0');
 	}
 
+$results = array();
+$sql = "SELECT callback_id, destination FROM callback";
+$results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
+if (!DB::IsError($results)) { // error - table must not be there
+	foreach ($results as $result) {
+		$old_dest  = $result['destination'];
+		$callback_id    = $result['callback_id'];
+
+		$new_dest = merge_ext_followme(trim($old_dest));
+		if ($new_dest != $old_dest) {
+			$sql = "UPDATE callback SET destination = '$new_dest' WHERE callback_id = $callback_id  AND destination = '$old_dest'";
+			$results = $db->query($sql);
+			if(DB::IsError($results)) {
+				die_freepbx($results->getMessage());
+			}
+		}
+	}
+}
+
 ?>

Modified: freepbx-modules/trunk/modules/callback/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/callback/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/callback/install.sql (original)
+++ freepbx-modules/trunk/modules/callback/install.sql Mon Apr  7 13:18:05 2008
@@ -1,1 +1,1 @@
-CREATE TABLE IF NOT EXISTS callback ( callback_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY , description VARCHAR( 50 ) , callbacknum VARCHAR( 100 ) , destination VARCHAR( 50 ) , sleep INT, deptname VARCHAR( 50 ));
+# empty file, for more details see http://freepbx.org/trac/ticket/1277

Modified: freepbx-modules/trunk/modules/callback/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/callback/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/callback/module.xml (original)
+++ freepbx-modules/trunk/modules/callback/module.xml Mon Apr  7 13:18:05 2008
@@ -1,18 +1,23 @@
 <module>
 	<rawname>callback</rawname>
 	<name>Callback</name>
-	<version>1.3.1</version>
+	<version>1.4.2.3</version>
 	<type>setup</type>
-	<category>Remote Access</category>
+	<category>Internal Options &amp; Configuration</category>
 	<menuitems>
 		<callback>Callback</callback>
 	</menuitems>
 	<changelog>
+	*1.4.2.3* changed categories
+	*1.4.2.2* bump for rc1
+	*1.4.2.1* changed freePBX to FreePBX
+	*1.4.2* merge findmefollow/core extension destinations if any
+	*1.4.1* Moved callback agi script from core to module
+	*1.4.0* SQLite3 support, fixes ticket:1793 (only for FreePBX 2.3)
 	*1.3.1* Add he_IL translation
 	*1.3* Fixed UI errors for new 2.2 look.
 	*1.2* First 2.2 release
 	</changelog>
-	<info>http://aussievoip.com.au/wiki/freePBX-Callback</info>
-	<location>release/2.2/callback-1.3.tgz</location>
-	<md5sum>233226526fd1fbf4601450a546233ad4</md5sum>
+	<location>release/2.3/callback-1.4.2.2.tgz</location>
+	<md5sum>c09ac8e91976cd082f52c89513ffd217</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/callforward/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/callforward/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/callforward/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/callforward/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -38,10 +38,11 @@
 
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
+	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
 	$ext->add($id, $c, '', new ext_playback('call-fwd-unconditional'));
 	$ext->add($id, $c, '', new ext_playback('please-enter-your&extension'));
 	$ext->add($id, $c, '', new ext_read('fromext', 'then-press-pound'));
-	$ext->add($id, $c, '', new ext_setvar('fromext', '${IF($["foo${fromext}"="foo"]?${CALLERID(number)}:${fromext})}'));	
+	$ext->add($id, $c, '', new ext_setvar('fromext', '${IF($["foo${fromext}"="foo"]?${AMPUSER}:${fromext})}'));	
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, 'startread', new ext_playback('ent-target-attendant'));
 	$ext->add($id, $c, '', new ext_read('toext', 'then-press-pound'));
@@ -59,9 +60,9 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_setvar('DB(CF/${CALLERID(number)})', '${EXTEN:'.$clen.'}')); 
-	$ext->add($id, $c, '', new ext_playback('call-fwd-unconditional&for&extension'));
-	$ext->add($id, $c, '', new ext_saydigits('${CALLERID(number)}'));
+	$ext->add($id, $c, '', new ext_setvar('DB(CF/${AMPUSER})', '${EXTEN:'.$clen.'}')); 
+	$ext->add($id, $c, '', new ext_playback('call-fwd-unconditional&for&extension'));
+	$ext->add($id, $c, '', new ext_saydigits('${AMPUSER}'));
 	$ext->add($id, $c, '', new ext_playback('is-set-to'));
 	$ext->add($id, $c, '', new ext_saydigits('${EXTEN:'.$clen.'}'));
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
@@ -97,7 +98,7 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_dbdel('CF/${CALLERID(number)}')); 
+	$ext->add($id, $c, '', new ext_dbdel('CF/${AMPUSER}')); 
 	$ext->add($id, $c, '', new ext_playback('call-fwd-unconditional&de-activated')); // $cmd,n,Playback(...)
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
 
@@ -125,10 +126,11 @@
 
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
+	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
 	$ext->add($id, $c, '', new ext_playback('call-fwd-on-busy'));
 	$ext->add($id, $c, '', new ext_playback('please-enter-your&extension'));
 	$ext->add($id, $c, '', new ext_read('fromext', 'then-press-pound'));
-	$ext->add($id, $c, '', new ext_setvar('fromext', '${IF($["foo${fromext}"="foo"]?${CALLERID(number)}:${fromext})}'));	
+	$ext->add($id, $c, '', new ext_setvar('fromext', '${IF($["foo${fromext}"="foo"]?${AMPUSER}:${fromext})}'));	
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, 'startread', new ext_playback('ent-target-attendant'));
 	$ext->add($id, $c, '', new ext_read('toext', 'then-press-pound'));
@@ -146,9 +148,9 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_setvar('DB(CFB/${CALLERID(number)})', '${EXTEN:'.$clen.'}')); 
-	$ext->add($id, $c, '', new ext_playback('call-fwd-on-busy&for&extension'));
-	$ext->add($id, $c, '', new ext_saydigits('${CALLERID(number)}'));
+	$ext->add($id, $c, '', new ext_setvar('DB(CFB/${AMPUSER})', '${EXTEN:'.$clen.'}')); 
+	$ext->add($id, $c, '', new ext_playback('call-fwd-on-busy&for&extension'));
+	$ext->add($id, $c, '', new ext_saydigits('${AMPUSER}'));
 	$ext->add($id, $c, '', new ext_playback('is-set-to'));
 	$ext->add($id, $c, '', new ext_saydigits('${EXTEN:'.$clen.'}'));
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
@@ -184,7 +186,7 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_dbdel('CFB/${CALLERID(number)}')); 
+	$ext->add($id, $c, '', new ext_dbdel('CFB/${AMPUSER}')); 
 	$ext->add($id, $c, '', new ext_playback('call-fwd-on-busy&de-activated')); // $cmd,n,Playback(...)
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
 
@@ -213,10 +215,11 @@
 	// prompt for extension
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
+	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
 	$ext->add($id, $c, '', new ext_playback('call-fwd-no-ans'));
 	$ext->add($id, $c, '', new ext_playback('please-enter-your&extension'));
 	$ext->add($id, $c, '', new ext_read('fromext', 'then-press-pound'));
-	$ext->add($id, $c, '', new ext_setvar('fromext', '${IF($["foo${fromext}"="foo"]?${CALLERID(number)}:${fromext})}'));
+	$ext->add($id, $c, '', new ext_setvar('fromext', '${IF($["foo${fromext}"="foo"]?${AMPUSER}:${fromext})}'));
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, 'startread', new ext_playback('ent-target-attendant'));
 	$ext->add($id, $c, '', new ext_read('toext', 'then-press-pound'));
@@ -235,9 +238,9 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_setvar('DB(CFU/${CALLERID(number)})', '${EXTEN:'.$clen.'}')); 
+	$ext->add($id, $c, '', new ext_setvar('DB(CFU/${AMPUSER})', '${EXTEN:'.$clen.'}')); 
 	$ext->add($id, $c, '', new ext_playback('call-fwd-no-ans&for&extension'));
-	$ext->add($id, $c, '', new ext_saydigits('${CALLERID(number)}'));
+	$ext->add($id, $c, '', new ext_saydigits('${AMPUSER}'));
 	$ext->add($id, $c, '', new ext_playback('is-set-to'));
 	$ext->add($id, $c, '', new ext_saydigits('${EXTEN:'.$clen.'}'));
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
@@ -254,7 +257,7 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_dbdel('CFU/${CALLERID(number)}')); 
+	$ext->add($id, $c, '', new ext_dbdel('CFU/${AMPUSER}')); 
 	$ext->add($id, $c, '', new ext_playback('call-fwd-no-ans&de-activated')); // $cmd,n,Playback(...)
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
 

Modified: freepbx-modules/trunk/modules/callforward/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/callforward/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/callforward/module.xml (original)
+++ freepbx-modules/trunk/modules/callforward/module.xml Mon Apr  7 13:18:05 2008
@@ -1,12 +1,16 @@
 <module>
 	<rawname>callforward</rawname>
 	<name>Call Forward</name>
-	<version>1.1</version>
-	<changelog>*1.1* First release for 2.2
+	<version>1.1.2</version>
+	<changelog>
+		*1.1.2* #2321 fixed CF AMPUSER(number) issue, syntax problem
+		*1.1.1.2* changed categories
+		*1.1.1.1* bump for rc1
+		*1.1.1* changed ${CALLERID(number)} to ${AMPUSER} to accomodate CID number masquerading
+		*1.1* First release for 2.2
 	</changelog>
 	<type>setup</type>
-	<category>Provides a Feature Code</category>
-	<location>release//2.2/callforward-1.0.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Features</info>
-	<md5sum>504e013e078300db4b0029964eccb1e0</md5sum>
+	<category>Internal Options &amp; Configuration</category>
+	<location>release/2.3/callforward-1.1.1.2.tgz</location>
+	<md5sum>83b552d1c530cbe2f7d6c0d5d892c85b</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/callforward/uninstall.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/callforward/uninstall.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/callforward/uninstall.php (original)
+++ freepbx-modules/trunk/modules/callforward/uninstall.php Mon Apr  7 13:18:05 2008
@@ -1,20 +1,17 @@
 <?php
 
-require_once('common/php-asmanager.php');
+// TODO, is this needed...?
+// is this global...? what if we include this files
+// from a function...?
+global $astman;
 
 // remove all Call Forward options in effect on extensions
-$astman = new AGI_AsteriskManager();
-if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {
-
+if ($astman) {
 	$astman->database_deltree('CF');
 	$astman->database_deltree('CFB');
 	$astman->database_deltree('CFU');
-
 } else {
-
 	fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
-
 }
-$astman->disconnect();
 
 ?>

Modified: freepbx-modules/trunk/modules/callwaiting/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/callwaiting/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/callwaiting/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/callwaiting/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -38,7 +38,7 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_setvar('DB(CW/${CALLERID(number)})', 'ENABLED')); 
+	$ext->add($id, $c, '', new ext_setvar('DB(CW/${AMPUSER})', 'ENABLED')); 
 	$ext->add($id, $c, '', new ext_playback('call-waiting&activated')); // $cmd,n,Playback(...)
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
 }
@@ -54,7 +54,7 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_dbdel('CW/${CALLERID(number)}')); 
+	$ext->add($id, $c, '', new ext_dbdel('CW/${AMPUSER}')); 
 	$ext->add($id, $c, '', new ext_playback('call-waiting&de-activated')); // $cmd,n,Playback(...)
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
 }

Modified: freepbx-modules/trunk/modules/callwaiting/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/callwaiting/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/callwaiting/module.xml (original)
+++ freepbx-modules/trunk/modules/callwaiting/module.xml Mon Apr  7 13:18:05 2008
@@ -1,15 +1,17 @@
 <module>
 	<rawname>callwaiting</rawname>
 	<name>Call Waiting</name>
-	<version>1.1.1</version>
+	<version>1.1.2.2</version>
 	<changelog>
+	*1.1.2.2* changed categories
+	*1.1.2.1* bump for rc1
+	*1.1.2* changed ${CALLERID(number)} to ${AMPUSER} to accomodate CID number masquerading
 	*1.1.1* Fixed typo Provdes to Provides*
 	*1.1* First release for 2.2
 	</changelog>
 	<type>setup</type>
-	<category>Provides a Feature Code</category>
+	<category>Internal Options &amp; Configuration</category>
 	<description>Provides an option to turn on/off call waiting</description>
-	<location>release/2.2/callwaiting-1.1.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Features</info>
-	<md5sum>f0544cca6ea0f0aef0214206baf12570</md5sum>
+	<location>release/2.3/callwaiting-1.1.2.1.tgz</location>
+	<md5sum>4c2f2ec4b40c94c3d0ec913191c4d1b1</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/cidlookup/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/cidlookup/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/cidlookup/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/cidlookup/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -122,7 +122,7 @@
 					// Search for number in the cache, if found lookupcidnum and return
 					if ($item['cidlookup_id'] != 0)	{
 						if ($item['cache'] == 1 && $item['sourcetype'] != 'internal') {
-							$ext->add('cidlookup', 'cidlookup_'.$item['cidlookup_id'], '', new ext_gotoif('$[${DB_EXISTS(cidname/${CALLERID(num)})} = 1]', 'cidlookup|cidlookup_return|1'));
+							$ext->add('cidlookup', 'cidlookup_'.$item['cidlookup_id'], '', new ext_gotoif('$[${DB_EXISTS(cidname/${CALLERID(num)})} = 1]', 'cidlookup,cidlookup_return,1'));
 						}
 					}
 

Modified: freepbx-modules/trunk/modules/cidlookup/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/cidlookup/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/cidlookup/install.php (original)
+++ freepbx-modules/trunk/modules/cidlookup/install.php Mon Apr  7 13:18:05 2008
@@ -1,15 +1,69 @@
 <?php
 
 global $db;
+global $amp_conf;
 
+$autoincrement = (($amp_conf["AMPDBENGINE"] == "sqlite") || ($amp_conf["AMPDBENGINE"] == "sqlite3")) ? "AUTOINCREMENT":"AUTO_INCREMENT";
+
+// create the tables
+$sql = "CREATE TABLE IF NOT EXISTS cidlookup (
+	cidlookup_id INTEGER NOT NULL PRIMARY KEY $autoincrement,
+	description varchar(50) NOT NULL,
+	sourcetype varchar(100) NOT NULL,
+	cache tinyint(1) NOT NULL default '0',
+	deptname varchar(30) default NULL,
+	http_host varchar(30) default NULL,
+	http_port varchar(30) default NULL,
+	http_username varchar(30) default NULL,
+	http_password varchar(30) default NULL,
+	http_path varchar(100) default NULL,
+	http_query varchar(100) default NULL,
+	mysql_host varchar(60) default NULL,
+	mysql_dbname varchar(60) default NULL,
+	mysql_query text,
+	mysql_username varchar(30) default NULL,
+	mysql_password varchar(30) default NULL
+);";
+$check = $db->query($sql);
+if (DB::IsError($check)) {
+        die_freepbx( "Can not create `cidlookup` table: " . $check->getMessage() .  "\n");
+}
+
+
+$sql = "CREATE TABLE IF NOT EXISTS cidlookup_incoming (
+	cidlookup_id INT NOT NULL,
+	extension VARCHAR(50),
+	cidnum VARCHAR(30),
+	channel VARCHAR(30)
+);";
+$check = $db->query($sql);
+if (DB::IsError($check)) {
+        die_freepbx( "Can not create `cidlookup_incomming` table: " . $check->getMessage() .  "\n");
+}
+
+// first update
 $sql = "SELECT cache FROM cidlookup";
 $check = $db->getRow($sql, DB_FETCHMODE_ASSOC);
-if(DB::IsError($check)) {
+if (DB::IsError($check)) {
 	// add new field
-	$sql = "ALTER TABLE cidlookup ADD cache TINYINT( 1 ) NOT NULL DEFAULT 0;";
+	$sql = "ALTER TABLE cidlookup ADD cache INTEGER NOT NULL DEFAULT 0;";
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getDebugInfo());
+		die_freepbx($result->getMessage());
 	}
 }
 
+// second update
+$sql = "SELECT cidlookup from incoming;";
+$check = $db->query($sql);
+if (DB::IsError($check)) {
+	$sql = "ALTER TABLE incoming ADD cidlookup INT(2);";
+	$check = $db->query($sql);
+	if (DB::IsError($check)) {
+		die_freepbx( "Can not alter `incoming` table: " . $check->getMessage() .  "\n");
+	}
+}
+
+
+?>
+

Modified: freepbx-modules/trunk/modules/cidlookup/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/cidlookup/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/cidlookup/install.sql (original)
+++ freepbx-modules/trunk/modules/cidlookup/install.sql Mon Apr  7 13:18:05 2008
@@ -1,29 +1,1 @@
-ALTER TABLE incoming ADD cidlookup INT(2);
-
-CREATE TABLE IF NOT EXISTS cidlookup (
-  cidlookup_id int(11) NOT NULL auto_increment,
-  description varchar(50) NOT NULL,
-  sourcetype varchar(100) NOT NULL,
-  cache tinyint(1) NOT NULL default '0',
-  deptname varchar(30) default NULL,
-  http_host varchar(30) default NULL,
-  http_port varchar(30) default NULL,
-  http_username varchar(30) default NULL,
-  http_password varchar(30) default NULL,
-  http_path varchar(100) default NULL,
-  http_query varchar(100) default NULL,
-  mysql_host varchar(60) default NULL,
-  mysql_dbname varchar(60) default NULL,
-  mysql_query text,
-  mysql_username varchar(30) default NULL,
-  mysql_password varchar(30) default NULL,
-  PRIMARY KEY  (cidlookup_id)
-);
-
-
-CREATE TABLE IF NOT EXISTS cidlookup_incoming (
-  cidlookup_id INT NOT NULL,
-	extension VARCHAR(50),
-	cidnum VARCHAR(30),
-	channel VARCHAR(30)
-);
+-- empty file, see http://freepbx.org/trac/ticket/1277

Modified: freepbx-modules/trunk/modules/cidlookup/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/cidlookup/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/cidlookup/module.xml (original)
+++ freepbx-modules/trunk/modules/cidlookup/module.xml Mon Apr  7 13:18:05 2008
@@ -1,20 +1,24 @@
 <module>
 	<rawname>cidlookup</rawname>
 	<name>Caller ID Lookup</name>
-	<version>1.1.1</version>
+	<version>1.2.1.3</version>
 	<description>Allows Caller ID Lookup of incoming calls against different sources (MySQL, HTTP, ENUM, Phonebook Module)</description>
 	<type>setup</type>
-	<category>CID &amp; Number Management</category>
+	<category>Inbound Call Control</category>
 	<menuitems>
-		<cidlookup>Caller Name Lookup Sources</cidlookup>
+		<cidlookup>CallerID Lookup Sources</cidlookup>
 	</menuitems>
 	<depends>
 		<engine>asterisk 1.2</engine>
 	</depends>
-	<location>release/2.2/cidlookup-1.1.tgz</location>
-	<md5sum>069bf88bc5cb14fd9b267a7264659c09</md5sum>
-	<info>http://freepbx.org/wiki/CallerIDLookup</info>
+	<location>release/2.3/cidlookup-1.2.1.2.tgz</location>
+	<md5sum>3c633027d46dbd51e66c67401839af77</md5sum>
 	<changelog>
+		*1.2.1.3* #2172 deprecated use of |, changed categories
+		*1.2.1.2* bump for rc1
+		*1.2.1.1* shorten menu name
+		*1.2.1* changed freePBX to FreePBX
+		*1.2.0* Added SQLite3 support, fixes ticket:1796 (FreePBX 2.3 only)
 		*1.1.1* Add he_IL translation
 		*1.1* First release for FreePBX 2.2 - Fixed compatibility issue with new UI
 		*1.0.4* Updated module.xml format

Modified: freepbx-modules/trunk/modules/cidlookup/uninstall.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/cidlookup/uninstall.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/cidlookup/uninstall.sql (original)
+++ freepbx-modules/trunk/modules/cidlookup/uninstall.sql Mon Apr  7 13:18:05 2008
@@ -1,4 +1,4 @@
-DROP TABLE cidlookup;
-DROP TABLE cidlookup_incoming;
+DROP TABLE IF EXISTS cidlookup;
+DROP TABLE IF EXISTS cidlookup_incoming;
 
 

Modified: freepbx-modules/trunk/modules/conferences/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/conferences/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/conferences/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/conferences/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -1,4 +1,4 @@
-<?php /* $Id: functions.inc.php 3990 2007-05-31 22:31:23Z p_lindheimer $ */
+<?php /* $Id: functions.inc.php 5208 2007-11-04 17:19:18Z p_lindheimer $ */
 
 // extend extensions class.
 // This example is about as simple as it gets
@@ -45,6 +45,7 @@
 function conferences_get_config($engine) {
 	global $ext;  // is this the best way to pass this?
 	global $conferences_conf;
+	global $version;
 	switch($engine) {
 		case "asterisk":
 			$ext->addInclude('from-internal-additional','ext-meetme');
@@ -63,11 +64,15 @@
 					
 					$roomnum = ltrim($item['0']);
 					$roomoptions = $room['options'];
+					if (version_compare($version, "1.4",">=")) {
+						$roomoptions = str_replace('i','I',$roomoptions);
+					}
 					$roomuserpin = $room['userpin'];
 					$roomadminpin = $room['adminpin'];
 					$roomjoinmsg = (isset($room['joinmsg'])?$room['joinmsg']:'');
 					
 					// entry point
+					$ext->add($contextname, $roomnum, '', new ext_macro('user-callerid'));
 					$ext->add($contextname, $roomnum, '', new ext_setvar('MEETME_ROOMNUM',$roomnum));
 					$ext->add($contextname, $roomnum, '', new ext_gotoif('$["${DIALSTATUS}" = "ANSWER"]',($roomuserpin == '' && $roomadminpin == '' ? 'USER' : 'READPIN')));			
 					$ext->add($contextname, $roomnum, '', new ext_answer(''));

Modified: freepbx-modules/trunk/modules/conferences/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/conferences/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/conferences/module.xml (original)
+++ freepbx-modules/trunk/modules/conferences/module.xml Mon Apr  7 13:18:05 2008
@@ -1,11 +1,15 @@
 <module>
 	<rawname>conferences</rawname>
 	<name>Conferences</name>
-	<version>1.2.1</version>
+	<version>1.2.2</version>
 	<type>setup</type>
 	<category>Internal Options &amp; Configuration</category>
 	<description>Allow creation of conference rooms (meet-me) where multiple people can talk together.</description>
 	<changelog>
+		*1.2.2* don't ask for name confirmation when recording names on Asterisk 1.3 (new option I replaces i)
+		*1.2.1.3* move Macro(user-callerid) to be called with each conf to accomodate future language settings
+		*1.2.1.2* add call to Macro(user-callerid) to get proper CID in Meetme Conference
+		*1.2.1.1* bump for rc1
 		*1.2.1* changed syntax error in meetme_additional.conf form '|' to ',' separator
 		*1.2* Fixed raising asterisk error on empty dialstatus #1708
 		*1.1.2* Add he_IL translation
@@ -15,7 +19,6 @@
 	<menuitems>
 		<conferences>Conferences</conferences>
 	</menuitems>
-	<location>release/2.2/conferences-1.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Conf</info>
-	<md5sum>fd9a9926fd7f27ef8ae9cadf036f4afe</md5sum>
+	<location>release/2.3/conferences-1.2.1.3.tgz</location>
+	<md5sum>1e7b8b1f9832b1f1cc54455f8bc953c3</md5sum>
 </module>

Added: freepbx-modules/trunk/modules/core/XML_Parser.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/XML_Parser.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/XML_Parser.php (added)
+++ freepbx-modules/trunk/modules/core/XML_Parser.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,685 @@
+<?php
+//
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2004 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 3.0 of the PHP license,       |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | 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 world-wide-web, please send a note to          |
+// | license at php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Author: Stig Bakken <ssb at fast.no>                                    |
+// |         Tomas V.V.Cox <cox at idecnet.com>                              |
+// |         Stephan Schmidt <schst at php-tools.net>                        |
+// +----------------------------------------------------------------------+
+//
+// $Id: Parser.php,v 1.26 2005/09/23 11:51:10 schst Exp $
+
+/**
+ * XML Parser class.
+ *
+ * This is an XML parser based on PHP's "xml" extension,
+ * based on the bundled expat library.
+ *
+ * @category XML
+ * @package XML_Parser
+ * @author  Stig Bakken <ssb at fast.no>
+ * @author  Tomas V.V.Cox <cox at idecnet.com>
+ * @author  Stephan Schmidt <schst at php-tools.net>
+ */
+
+/**
+ * uses PEAR's error handling
+ */
+//require_once 'PEAR.php';
+
+/**
+ * resource could not be created
+ */
+define('XML_PARSER_ERROR_NO_RESOURCE', 200);
+
+/**
+ * unsupported mode
+ */
+define('XML_PARSER_ERROR_UNSUPPORTED_MODE', 201);
+
+/**
+ * invalid encoding was given
+ */
+define('XML_PARSER_ERROR_INVALID_ENCODING', 202);
+
+/**
+ * specified file could not be read
+ */
+define('XML_PARSER_ERROR_FILE_NOT_READABLE', 203);
+
+/**
+ * invalid input
+ */
+define('XML_PARSER_ERROR_INVALID_INPUT', 204);
+
+/**
+ * remote file cannot be retrieved in safe mode
+ */
+define('XML_PARSER_ERROR_REMOTE', 205);
+
+/**
+ * XML Parser class.
+ *
+ * This is an XML parser based on PHP's "xml" extension,
+ * based on the bundled expat library.
+ *
+ * Notes:
+ * - It requires PHP 4.0.4pl1 or greater
+ * - From revision 1.17, the function names used by the 'func' mode
+ *   are in the format "xmltag_$elem", for example: use "xmltag_name"
+ *   to handle the <name></name> tags of your xml file.
+ *
+ * @category XML
+ * @package XML_Parser
+ * @author  Stig Bakken <ssb at fast.no>
+ * @author  Tomas V.V.Cox <cox at idecnet.com>
+ * @author  Stephan Schmidt <schst at php-tools.net>
+ * @todo    create XML_Parser_Namespace to parse documents with namespaces
+ * @todo    create XML_Parser_Pull
+ * @todo    Tests that need to be made:
+ *          - mixing character encodings
+ *          - a test using all expat handlers
+ *          - options (folding, output charset)
+ *          - different parsing modes
+ */
+class XML_Parser extends PEAR
+{
+    // {{{ properties
+
+   /**
+     * XML parser handle
+     *
+     * @var  resource
+     * @see  xml_parser_create()
+     */
+    var $parser;
+
+    /**
+     * File handle if parsing from a file
+     *
+     * @var  resource
+     */
+    var $fp;
+
+    /**
+     * Whether to do case folding
+     *
+     * If set to true, all tag and attribute names will
+     * be converted to UPPER CASE.
+     *
+     * @var  boolean
+     */
+    var $folding = true;
+
+    /**
+     * Mode of operation, one of "event" or "func"
+     *
+     * @var  string
+     */
+    var $mode;
+
+    /**
+     * Mapping from expat handler function to class method.
+     *
+     * @var  array
+     */
+    var $handler = array(
+        'character_data_handler'            => 'cdataHandler',
+        'default_handler'                   => 'defaultHandler',
+        'processing_instruction_handler'    => 'piHandler',
+        'unparsed_entity_decl_handler'      => 'unparsedHandler',
+        'notation_decl_handler'             => 'notationHandler',
+        'external_entity_ref_handler'       => 'entityrefHandler'
+    );
+
+    /**
+     * source encoding
+     *
+     * @var string
+     */
+    var $srcenc;
+
+    /**
+     * target encoding
+     *
+     * @var string
+     */
+    var $tgtenc;
+
+    /**
+     * handler object
+     *
+     * @var object
+     */
+    var $_handlerObj;
+
+    // }}}
+    // {{{ constructor
+
+    /**
+     * Creates an XML parser.
+     *
+     * This is needed for PHP4 compatibility, it will
+     * call the constructor, when a new instance is created.
+     *
+     * @param string $srcenc source charset encoding, use NULL (default) to use
+     *                       whatever the document specifies
+     * @param string $mode   how this parser object should work, "event" for
+     *                       startelement/endelement-type events, "func"
+     *                       to have it call functions named after elements
+     * @param string $tgenc  a valid target encoding
+     */
+    function XML_Parser($srcenc = null, $mode = 'event', $tgtenc = null)
+    {
+        XML_Parser::__construct($srcenc, $mode, $tgtenc);
+    }
+    // }}}
+
+    /**
+     * PHP5 constructor
+     *
+     * @param string $srcenc source charset encoding, use NULL (default) to use
+     *                       whatever the document specifies
+     * @param string $mode   how this parser object should work, "event" for
+     *                       startelement/endelement-type events, "func"
+     *                       to have it call functions named after elements
+     * @param string $tgenc  a valid target encoding
+     */
+    function __construct($srcenc = null, $mode = 'event', $tgtenc = null)
+    {
+        $this->PEAR('XML_Parser_Error');
+
+        $this->mode   = $mode;
+        $this->srcenc = $srcenc;
+        $this->tgtenc = $tgtenc;
+    }
+    // }}}
+
+    /**
+     * Sets the mode of the parser.
+     *
+     * Possible modes are:
+     * - func
+     * - event
+     *
+     * You can set the mode using the second parameter
+     * in the constructor.
+     *
+     * This method is only needed, when switching to a new
+     * mode at a later point.
+     *
+     * @access  public
+     * @param   string          mode, either 'func' or 'event'
+     * @return  boolean|object  true on success, PEAR_Error otherwise   
+     */
+    function setMode($mode)
+    {
+        if ($mode != 'func' && $mode != 'event') {
+            $this->raiseError('Unsupported mode given', XML_PARSER_ERROR_UNSUPPORTED_MODE);
+        }
+
+        $this->mode = $mode;
+        return true;
+    }
+
+    /**
+     * Sets the object, that will handle the XML events
+     *
+     * This allows you to create a handler object independent of the
+     * parser object that you are using and easily switch the underlying
+     * parser.
+     *
+     * If no object will be set, XML_Parser assumes that you
+     * extend this class and handle the events in $this.
+     *
+     * @access  public
+     * @param   object      object to handle the events
+     * @return  boolean     will always return true
+     * @since   v1.2.0beta3
+     */
+    function setHandlerObj(&$obj)
+    {
+        $this->_handlerObj = &$obj;
+        return true;
+    }
+
+    /**
+     * Init the element handlers
+     *
+     * @access  private
+     */
+    function _initHandlers()
+    {
+        if (!is_resource($this->parser)) {
+            return false;
+        }
+
+        if (!is_object($this->_handlerObj)) {
+            $this->_handlerObj = &$this;
+        }
+        switch ($this->mode) {
+
+            case 'func':
+                xml_set_object($this->parser, $this->_handlerObj);
+                xml_set_element_handler($this->parser, array(&$this, 'funcStartHandler'), array(&$this, 'funcEndHandler'));
+                break;
+
+            case 'event':
+                xml_set_object($this->parser, $this->_handlerObj);
+                xml_set_element_handler($this->parser, 'startHandler', 'endHandler');
+                break;
+            default:
+                return $this->raiseError('Unsupported mode given', XML_PARSER_ERROR_UNSUPPORTED_MODE);
+                break;
+        }
+
+
+        /**
+         * set additional handlers for character data, entities, etc.
+         */
+        foreach ($this->handler as $xml_func => $method) {
+            if (method_exists($this->_handlerObj, $method)) {
+                $xml_func = 'xml_set_' . $xml_func;
+                $xml_func($this->parser, $method);
+            }
+		}
+    }
+
+    // {{{ _create()
+
+    /**
+     * create the XML parser resource
+     *
+     * Has been moved from the constructor to avoid
+     * problems with object references.
+     *
+     * Furthermore it allows us returning an error
+     * if something fails.
+     *
+     * @access   private
+     * @return   boolean|object     true on success, PEAR_Error otherwise
+     *
+     * @see xml_parser_create
+     */
+    function _create()
+    {
+        if ($this->srcenc === null) {
+            $xp = @xml_parser_create();
+        } else {
+            $xp = @xml_parser_create($this->srcenc);
+        }
+        if (is_resource($xp)) {
+            if ($this->tgtenc !== null) {
+                if (!@xml_parser_set_option($xp, XML_OPTION_TARGET_ENCODING,
+                                            $this->tgtenc)) {
+                    return $this->raiseError('invalid target encoding', XML_PARSER_ERROR_INVALID_ENCODING);
+                }
+            }
+            $this->parser = $xp;
+            $result = $this->_initHandlers($this->mode);
+            if ($this->isError($result)) {
+                return $result;
+            }
+            xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, $this->folding);
+
+            return true;
+        }
+        return $this->raiseError('Unable to create XML parser resource.', XML_PARSER_ERROR_NO_RESOURCE);
+    }
+
+    // }}}
+    // {{{ reset()
+
+    /**
+     * Reset the parser.
+     *
+     * This allows you to use one parser instance
+     * to parse multiple XML documents.
+     *
+     * @access   public
+     * @return   boolean|object     true on success, PEAR_Error otherwise
+     */
+    function reset()
+    {
+        $result = $this->_create();
+        if ($this->isError( $result )) {
+            return $result;
+        }
+        return true;
+    }
+
+    // }}}
+    // {{{ setInputFile()
+
+    /**
+     * Sets the input xml file to be parsed
+     *
+     * @param    string      Filename (full path)
+     * @return   resource    fopen handle of the given file
+     * @throws   XML_Parser_Error
+     * @see      setInput(), setInputString(), parse()
+     * @access   public
+     */
+    function setInputFile($file)
+    {
+        /**
+         * check, if file is a remote file
+         */
+        if (eregi('^(http|ftp)://', substr($file, 0, 10))) {
+            if (!ini_get('allow_url_fopen')) {
+            	return $this->raiseError('Remote files cannot be parsed, as safe mode is enabled.', XML_PARSER_ERROR_REMOTE);
+            }
+        }
+        
+        $fp = @fopen($file, 'rb');
+        if (is_resource($fp)) {
+            $this->fp = $fp;
+            return $fp;
+        }
+        return $this->raiseError('File could not be opened.', XML_PARSER_ERROR_FILE_NOT_READABLE);
+    }
+
+    // }}}
+    // {{{ setInputString()
+    
+    /**
+     * XML_Parser::setInputString()
+     * 
+     * Sets the xml input from a string
+     * 
+     * @param string $data a string containing the XML document
+     * @return null
+     **/
+    function setInputString($data)
+    {
+        $this->fp = $data;
+        return null;
+    }
+    
+    // }}}
+    // {{{ setInput()
+
+    /**
+     * Sets the file handle to use with parse().
+     *
+     * You should use setInputFile() or setInputString() if you
+     * pass a string 
+     *
+     * @param    mixed  $fp  Can be either a resource returned from fopen(),
+     *                       a URL, a local filename or a string.
+     * @access   public
+     * @see      parse()
+     * @uses     setInputString(), setInputFile()
+     */
+    function setInput($fp)
+    {
+        if (is_resource($fp)) {
+            $this->fp = $fp;
+            return true;
+        }
+        // see if it's an absolute URL (has a scheme at the beginning)
+        elseif (eregi('^[a-z]+://', substr($fp, 0, 10))) {
+            return $this->setInputFile($fp);
+        }
+        // see if it's a local file
+        elseif (file_exists($fp)) {
+            return $this->setInputFile($fp);
+        }
+        // it must be a string
+        else {
+            $this->fp = $fp;
+            return true;
+        }
+
+        return $this->raiseError('Illegal input format', XML_PARSER_ERROR_INVALID_INPUT);
+    }
+
+    // }}}
+    // {{{ parse()
+
+    /**
+     * Central parsing function.
+     *
+     * @return   true|object PEAR error     returns true on success, or a PEAR_Error otherwise
+     * @access   public
+     */
+    function parse()
+    {
+        /**
+         * reset the parser
+         */
+        $result = $this->reset();
+        if ($this->isError($result)) {
+            return $result;
+        }
+        // if $this->fp was fopened previously
+        if (is_resource($this->fp)) {
+        
+            while ($data = fread($this->fp, 4096)) {
+                if (!$this->_parseString($data, feof($this->fp))) {
+                    $error = &$this->raiseError();
+                    $this->free();
+                    return $error;
+                }
+            }
+        // otherwise, $this->fp must be a string
+        } else {
+            if (!$this->_parseString($this->fp, true)) {
+                $error = &$this->raiseError();
+                $this->free();
+                return $error;
+            }
+        }
+        $this->free();
+
+        return true;
+    }
+
+    /**
+     * XML_Parser::_parseString()
+     * 
+     * @param string $data
+     * @param boolean $eof
+     * @return bool
+     * @access private
+     * @see parseString()
+     **/
+    function _parseString($data, $eof = false)
+    {
+        return xml_parse($this->parser, $data, $eof);
+    }
+    
+    // }}}
+    // {{{ parseString()
+
+    /**
+     * XML_Parser::parseString()
+     * 
+     * Parses a string.
+     *
+     * @param    string  $data XML data
+     * @param    boolean $eof  If set and TRUE, data is the last piece of data sent in this parser
+     * @throws   XML_Parser_Error
+     * @return   Pear Error|true   true on success or a PEAR Error
+     * @see      _parseString()
+     */
+    function parseString($data, $eof = false)
+    {
+        if (!isset($this->parser) || !is_resource($this->parser)) {
+            $this->reset();
+        }
+        
+        if (!$this->_parseString($data, $eof)) {
+           $error = &$this->raiseError();
+           $this->free();
+           return $error;
+        }
+
+        if ($eof === true) {
+            $this->free();
+        }
+        return true;
+    }
+    
+    /**
+     * XML_Parser::free()
+     * 
+     * Free the internal resources associated with the parser
+     * 
+     * @return null
+     **/
+    function free()
+    {
+        if (isset($this->parser) && is_resource($this->parser)) {
+            xml_parser_free($this->parser);
+            unset( $this->parser );
+        }
+        if (isset($this->fp) && is_resource($this->fp)) {
+            fclose($this->fp);
+        }
+        unset($this->fp);
+        return null;
+    }
+    
+    /**
+     * XML_Parser::raiseError()
+     * 
+     * Throws a XML_Parser_Error
+     * 
+     * @param string  $msg   the error message
+     * @param integer $ecode the error message code
+     * @return XML_Parser_Error 
+     **/
+    function raiseError($msg = null, $ecode = 0)
+    {
+        $msg = !is_null($msg) ? $msg : $this->parser;
+        $err = &new XML_Parser_Error($msg, $ecode);
+        return parent::raiseError($err);
+    }
+    
+    // }}}
+    // {{{ funcStartHandler()
+
+    function funcStartHandler($xp, $elem, $attribs)
+    {
+        $func = 'xmltag_' . $elem;
+        if (strchr($func, '.')) {
+            $func = str_replace('.', '_', $func);
+        }
+        if (method_exists($this->_handlerObj, $func)) {
+            call_user_func(array(&$this->_handlerObj, $func), $xp, $elem, $attribs);
+        } elseif (method_exists($this->_handlerObj, 'xmltag')) {
+            call_user_func(array(&$this->_handlerObj, 'xmltag'), $xp, $elem, $attribs);
+        }
+    }
+
+    // }}}
+    // {{{ funcEndHandler()
+
+    function funcEndHandler($xp, $elem)
+    {
+        $func = 'xmltag_' . $elem . '_';
+        if (strchr($func, '.')) {
+            $func = str_replace('.', '_', $func);
+        }
+        if (method_exists($this->_handlerObj, $func)) {
+            call_user_func(array(&$this->_handlerObj, $func), $xp, $elem);
+        } elseif (method_exists($this->_handlerObj, 'xmltag_')) {
+            call_user_func(array(&$this->_handlerObj, 'xmltag_'), $xp, $elem);
+        }
+    }
+
+    // }}}
+    // {{{ startHandler()
+
+    /**
+     *
+     * @abstract
+     */
+    function startHandler($xp, $elem, &$attribs)
+    {
+        return NULL;
+    }
+
+    // }}}
+    // {{{ endHandler()
+
+    /**
+     *
+     * @abstract
+     */
+    function endHandler($xp, $elem)
+    {
+        return NULL;
+    }
+
+
+    // }}}me
+}
+
+/**
+ * error class, replaces PEAR_Error
+ *
+ * An instance of this class will be returned
+ * if an error occurs inside XML_Parser.
+ *
+ * There are three advantages over using the standard PEAR_Error:
+ * - All messages will be prefixed
+ * - check for XML_Parser error, using is_a( $error, 'XML_Parser_Error' )
+ * - messages can be generated from the xml_parser resource
+ *
+ * @package XML_Parser
+ * @access  public
+ * @see     PEAR_Error
+ */
+class XML_Parser_Error extends PEAR_Error
+{
+    // {{{ properties
+
+   /**
+    * prefix for all messages
+    *
+    * @var      string
+    */    
+    var $error_message_prefix = 'XML_Parser: ';
+
+    // }}}
+    // {{{ constructor()
+   /**
+    * construct a new error instance
+    *
+    * You may either pass a message or an xml_parser resource as first
+    * parameter. If a resource has been passed, the last error that
+    * happened will be retrieved and returned.
+    *
+    * @access   public
+    * @param    string|resource     message or parser resource
+    * @param    integer             error code
+    * @param    integer             error handling
+    * @param    integer             error level
+    */    
+    function XML_Parser_Error($msgorparser = 'unknown error', $code = 0, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE)
+    {
+        if (is_resource($msgorparser)) {
+            $code = xml_get_error_code($msgorparser);
+            $msgorparser = sprintf('%s at XML input line %d:%d',
+                                   xml_error_string($code),
+                                   xml_get_current_line_number($msgorparser),
+                                   xml_get_current_column_number($msgorparser));
+        }
+        $this->PEAR_Error($msgorparser, $code, $mode, $level);
+    }
+    // }}}
+}
+?>

Added: freepbx-modules/trunk/modules/core/XML_Unserializer.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/XML_Unserializer.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/XML_Unserializer.php (added)
+++ freepbx-modules/trunk/modules/core/XML_Unserializer.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,856 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * XML_Unserializer
+ *
+ * Parses any XML document into PHP data structures.
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category   XML
+ * @package    XML_Serializer
+ * @author     Stephan Schmidt <schst at php.net>
+ * @copyright  1997-2005 The PHP Group
+ * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version    CVS: $Id: Unserializer.php,v 1.39 2005/09/28 11:19:56 schst Exp $
+ * @link       http://pear.php.net/package/XML_Serializer
+ * @see        XML_Unserializer
+ */
+
+/**
+ * uses PEAR error managemt
+ */
+//require_once 'PEAR.php';
+
+/**
+ * uses XML_Parser to unserialize document
+ */
+//require_once 'XML/Parser.php';
+
+/**
+ * option: Convert nested tags to array or object
+ *
+ * Possible values:
+ * - array
+ * - object
+ * - associative array to define this option per tag name
+ */
+define('XML_UNSERIALIZER_OPTION_COMPLEXTYPE', 'complexType');
+
+/**
+ * option: Name of the attribute that stores the original key
+ *
+ * Possible values:
+ * - any string
+ */
+define('XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY', 'keyAttribute');
+
+/**
+ * option: Name of the attribute that stores the type
+ *
+ * Possible values:
+ * - any string
+ */
+define('XML_UNSERIALIZER_OPTION_ATTRIBUTE_TYPE', 'typeAttribute');
+
+/**
+ * option: Name of the attribute that stores the class name
+ *
+ * Possible values:
+ * - any string
+ */
+define('XML_UNSERIALIZER_OPTION_ATTRIBUTE_CLASS', 'classAttribute');
+
+/**
+ * option: Whether to use the tag name as a class name
+ *
+ * Possible values:
+ * - true or false
+ */
+define('XML_UNSERIALIZER_OPTION_TAG_AS_CLASSNAME', 'tagAsClass');
+
+/**
+ * option: Name of the default class
+ *
+ * Possible values:
+ * - any string
+ */
+define('XML_UNSERIALIZER_OPTION_DEFAULT_CLASS', 'defaultClass');
+
+/**
+ * option: Whether to parse attributes
+ *
+ * Possible values:
+ * - true or false
+ */
+define('XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE', 'parseAttributes');
+
+/**
+ * option: Key of the array to store attributes (if any)
+ *
+ * Possible values:
+ * - any string
+ * - false (disabled)
+ */
+define('XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY', 'attributesArray');
+
+/**
+ * option: string to prepend attribute name (if any)
+ *
+ * Possible values:
+ * - any string
+ * - false (disabled)
+ */
+define('XML_UNSERIALIZER_OPTION_ATTRIBUTES_PREPEND', 'prependAttributes');
+
+/**
+ * option: key to store the content, if XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE is used
+ *
+ * Possible values:
+ * - any string
+ */
+define('XML_UNSERIALIZER_OPTION_CONTENT_KEY', 'contentName');
+
+/**
+ * option: map tag names
+ *
+ * Possible values:
+ * - associative array
+ */
+define('XML_UNSERIALIZER_OPTION_TAG_MAP', 'tagMap');
+
+/**
+ * option: list of tags that will always be enumerated
+ *
+ * Possible values:
+ * - indexed array
+ */
+define('XML_UNSERIALIZER_OPTION_FORCE_ENUM', 'forceEnum');
+
+/**
+ * option: Encoding of the XML document
+ *
+ * Possible values:
+ * - UTF-8
+ * - ISO-8859-1
+ */
+define('XML_UNSERIALIZER_OPTION_ENCODING_SOURCE', 'encoding');
+
+/**
+ * option: Desired target encoding of the data
+ *
+ * Possible values:
+ * - UTF-8
+ * - ISO-8859-1
+ */
+define('XML_UNSERIALIZER_OPTION_ENCODING_TARGET', 'targetEncoding');
+
+/**
+ * option: Callback that will be applied to textual data
+ *
+ * Possible values:
+ * - any valid PHP callback
+ */
+define('XML_UNSERIALIZER_OPTION_DECODE_FUNC', 'decodeFunction');
+
+/**
+ * option: whether to return the result of the unserialization from unserialize()
+ *
+ * Possible values:
+ * - true
+ * - false (default)
+ */
+define('XML_UNSERIALIZER_OPTION_RETURN_RESULT', 'returnResult');
+
+/**
+ * option: set the whitespace behaviour
+ *
+ * Possible values:
+ * - XML_UNSERIALIZER_WHITESPACE_KEEP
+ * - XML_UNSERIALIZER_WHITESPACE_TRIM
+ * - XML_UNSERIALIZER_WHITESPACE_NORMALIZE
+ */
+define('XML_UNSERIALIZER_OPTION_WHITESPACE', 'whitespace');
+
+/**
+ * Keep all whitespace
+ */
+define('XML_UNSERIALIZER_WHITESPACE_KEEP', 'keep');
+
+/**
+ * remove whitespace from start and end of the data
+ */
+define('XML_UNSERIALIZER_WHITESPACE_TRIM', 'trim');
+
+/**
+ * normalize whitespace
+ */
+define('XML_UNSERIALIZER_WHITESPACE_NORMALIZE', 'normalize');
+
+/**
+ * option: whether to ovverride all options that have been set before
+ *
+ * Possible values:
+ * - true
+ * - false (default)
+ */
+define('XML_UNSERIALIZER_OPTION_OVERRIDE_OPTIONS', 'overrideOptions');
+
+/**
+ * option: list of tags, that will not be used as keys
+ */
+define('XML_UNSERIALIZER_OPTION_IGNORE_KEYS', 'ignoreKeys');
+
+/**
+ * option: whether to use type guessing for scalar values
+ */
+define('XML_UNSERIALIZER_OPTION_GUESS_TYPES', 'guessTypes');
+
+/**
+ * error code for no serialization done
+ */
+define('XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION', 151);
+
+/**
+ * XML_Unserializer
+ *
+ * class to unserialize XML documents that have been created with
+ * XML_Serializer. To unserialize an XML document you have to add
+ * type hints to the XML_Serializer options.
+ *
+ * If no type hints are available, XML_Unserializer will guess how
+ * the tags should be treated, that means complex structures will be
+ * arrays and tags with only CData in them will be strings.
+ *
+ * <code>
+ * require_once 'XML/Unserializer.php';
+ *
+ * //  be careful to always use the ampersand in front of the new operator
+ * $unserializer = &new XML_Unserializer();
+ *
+ * $unserializer->unserialize($xml);
+ *
+ * $data = $unserializer->getUnserializedData();
+ * <code>
+ *
+ *
+ * @category   XML
+ * @package    XML_Serializer
+ * @author     Stephan Schmidt <schst at php.net>
+ * @copyright  1997-2005 The PHP Group
+ * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version    Release: 0.18.0
+ * @link       http://pear.php.net/package/XML_Serializer
+ * @see        XML_Serializer
+ */
+class XML_Unserializer extends PEAR
+{
+   /**
+    * list of all available options
+    *
+    * @access private
+    * @var    array
+    */
+    var $_knownOptions = array(
+                                XML_UNSERIALIZER_OPTION_COMPLEXTYPE,
+                                XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY,
+                                XML_UNSERIALIZER_OPTION_ATTRIBUTE_TYPE,
+                                XML_UNSERIALIZER_OPTION_ATTRIBUTE_CLASS,
+                                XML_UNSERIALIZER_OPTION_TAG_AS_CLASSNAME,
+                                XML_UNSERIALIZER_OPTION_DEFAULT_CLASS,
+                                XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE,
+                                XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY,
+                                XML_UNSERIALIZER_OPTION_ATTRIBUTES_PREPEND,
+                                XML_UNSERIALIZER_OPTION_CONTENT_KEY,
+                                XML_UNSERIALIZER_OPTION_TAG_MAP,
+                                XML_UNSERIALIZER_OPTION_FORCE_ENUM,
+                                XML_UNSERIALIZER_OPTION_ENCODING_SOURCE,
+                                XML_UNSERIALIZER_OPTION_ENCODING_TARGET,
+                                XML_UNSERIALIZER_OPTION_DECODE_FUNC,
+                                XML_UNSERIALIZER_OPTION_RETURN_RESULT,
+                                XML_UNSERIALIZER_OPTION_WHITESPACE,
+                                XML_UNSERIALIZER_OPTION_IGNORE_KEYS,
+                                XML_UNSERIALIZER_OPTION_GUESS_TYPES
+                              );
+   /**
+    * default options for the serialization
+    *
+    * @access private
+    * @var    array
+    */
+    var $_defaultOptions = array(
+                         XML_UNSERIALIZER_OPTION_COMPLEXTYPE         => 'array',                // complex types will be converted to arrays, if no type hint is given
+                         XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY       => '_originalKey',         // get array key/property name from this attribute
+                         XML_UNSERIALIZER_OPTION_ATTRIBUTE_TYPE      => '_type',                // get type from this attribute
+                         XML_UNSERIALIZER_OPTION_ATTRIBUTE_CLASS     => '_class',               // get class from this attribute (if not given, use tag name)
+                         XML_UNSERIALIZER_OPTION_TAG_AS_CLASSNAME    => true,                   // use the tagname as the classname
+                         XML_UNSERIALIZER_OPTION_DEFAULT_CLASS       => 'stdClass',             // name of the class that is used to create objects
+                         XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE    => false,                  // parse the attributes of the tag into an array
+                         XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY => false,                  // parse them into sperate array (specify name of array here)
+                         XML_UNSERIALIZER_OPTION_ATTRIBUTES_PREPEND  => '',                     // prepend attribute names with this string
+                         XML_UNSERIALIZER_OPTION_CONTENT_KEY         => '_content',             // put cdata found in a tag that has been converted to a complex type in this key
+                         XML_UNSERIALIZER_OPTION_TAG_MAP             => array(),                // use this to map tagnames
+                         XML_UNSERIALIZER_OPTION_FORCE_ENUM          => array(),                // these tags will always be an indexed array
+                         XML_UNSERIALIZER_OPTION_ENCODING_SOURCE     => null,                   // specify the encoding character of the document to parse
+                         XML_UNSERIALIZER_OPTION_ENCODING_TARGET     => null,                   // specify the target encoding
+                         XML_UNSERIALIZER_OPTION_DECODE_FUNC         => null,                   // function used to decode data
+                         XML_UNSERIALIZER_OPTION_RETURN_RESULT       => false,                  // unserialize() returns the result of the unserialization instead of true
+                         XML_UNSERIALIZER_OPTION_WHITESPACE          => XML_UNSERIALIZER_WHITESPACE_TRIM, // remove whitespace around data
+                         XML_UNSERIALIZER_OPTION_IGNORE_KEYS         => array(),                // List of tags that will automatically be added to the parent, instead of adding a new key
+                         XML_UNSERIALIZER_OPTION_GUESS_TYPES         => false                   // Whether to use type guessing
+                        );
+
+   /**
+    * current options for the serialization
+    *
+    * @access public
+    * @var    array
+    */
+    var $options = array();
+
+   /**
+    * unserialized data
+    *
+    * @access private
+    * @var    string
+    */
+    var $_unserializedData = null;
+
+   /**
+    * name of the root tag
+    *
+    * @access private
+    * @var    string
+    */
+    var $_root = null;
+
+   /**
+    * stack for all data that is found
+    *
+    * @access private
+    * @var    array
+    */
+    var $_dataStack  =   array();
+
+   /**
+    * stack for all values that are generated
+    *
+    * @access private
+    * @var    array
+    */
+    var $_valStack  =   array();
+
+   /**
+    * current tag depth
+    *
+    * @access private
+    * @var    int
+    */
+    var $_depth = 0;
+
+   /**
+    * XML_Parser instance
+    *
+    * @access   private
+    * @var      object XML_Parser
+    */
+    var $_parser = null;
+    
+   /**
+    * constructor
+    *
+    * @access   public
+    * @param    mixed   $options    array containing options for the unserialization
+    */
+    function XML_Unserializer($options = null)
+    {
+        if (is_array($options)) {
+            $this->options = array_merge($this->_defaultOptions, $options);
+        } else {
+            $this->options = $this->_defaultOptions;
+        }
+    }
+
+   /**
+    * return API version
+    *
+    * @access   public
+    * @static
+    * @return   string  $version API version
+    */
+    function apiVersion()
+    {
+        return '0.18.0';
+    }
+
+   /**
+    * reset all options to default options
+    *
+    * @access   public
+    * @see      setOption(), XML_Unserializer(), setOptions()
+    */
+    function resetOptions()
+    {
+        $this->options = $this->_defaultOptions;
+    }
+
+   /**
+    * set an option
+    *
+    * You can use this method if you do not want to set all options in the constructor
+    *
+    * @access   public
+    * @see      resetOption(), XML_Unserializer(), setOptions()
+    */
+    function setOption($name, $value)
+    {
+        $this->options[$name] = $value;
+    }
+
+   /**
+    * sets several options at once
+    *
+    * You can use this method if you do not want to set all options in the constructor
+    *
+    * @access   public
+    * @see      resetOption(), XML_Unserializer(), setOption()
+    */
+    function setOptions($options)
+    {
+        $this->options = array_merge($this->options, $options);
+    }
+
+   /**
+    * unserialize data
+    *
+    * @access   public
+    * @param    mixed    $data     data to unserialize (string, filename or resource)
+    * @param    boolean  $isFile   data should be treated as a file
+    * @param    array    $options  options that will override the global options for this call
+    * @return   boolean  $success
+    */
+    function unserialize($data, $isFile = false, $options = null)
+    {
+        $this->_unserializedData = null;
+        $this->_root = null;
+
+        // if options have been specified, use them instead
+        // of the previously defined ones
+        if (is_array($options)) {
+            $optionsBak = $this->options;
+            if (isset($options[XML_UNSERIALIZER_OPTION_OVERRIDE_OPTIONS]) && $options[XML_UNSERIALIZER_OPTION_OVERRIDE_OPTIONS] == true) {
+                $this->options = array_merge($this->_defaultOptions, $options);
+            } else {
+                $this->options = array_merge($this->options, $options);
+            }
+        } else {
+            $optionsBak = null;
+        }
+
+        $this->_valStack = array();
+        $this->_dataStack = array();
+        $this->_depth = 0;
+
+        $this->_createParser();
+        
+        if (is_string($data)) {
+            if ($isFile) {
+                $result = $this->_parser->setInputFile($data);
+                if (PEAR::isError($result)) {
+                    return $result;
+                }
+                $result = $this->_parser->parse();
+            } else {
+                $result = $this->_parser->parseString($data,true);
+            }
+        } else {
+           $this->_parser->setInput($data);
+           $result = $this->_parser->parse();
+        }
+
+        if ($this->options[XML_UNSERIALIZER_OPTION_RETURN_RESULT] === true) {
+        	$return = $this->_unserializedData;
+        } else {
+            $return = true;
+        }
+
+        if ($optionsBak !== null) {
+            $this->options = $optionsBak;
+        }
+
+        if (PEAR::isError($result)) {
+            return $result;
+        }
+
+        return $return;
+    }
+
+   /**
+    * get the result of the serialization
+    *
+    * @access public
+    * @return string  $serializedData
+    */
+    function getUnserializedData()
+    {
+        if ($this->_root === null) {
+            return $this->raiseError('No unserialized data available. Use XML_Unserializer::unserialize() first.', XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION);
+        }
+        return $this->_unserializedData;
+    }
+
+   /**
+    * get the name of the root tag
+    *
+    * @access public
+    * @return string  $rootName
+    */
+    function getRootName()
+    {
+        if ($this->_root === null) {
+            return $this->raiseError('No unserialized data available. Use XML_Unserializer::unserialize() first.', XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION);
+        }
+        return $this->_root;
+    }
+
+   /**
+    * Start element handler for XML parser
+    *
+    * @access private
+    * @param  object $parser  XML parser object
+    * @param  string $element XML element
+    * @param  array  $attribs attributes of XML tag
+    * @return void
+    */
+    function startHandler($parser, $element, $attribs)
+    {
+        if (isset($attribs[$this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_TYPE]])) {
+            $type = $attribs[$this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_TYPE]];
+            $guessType = false;
+        } else {
+            $type = 'string';
+            if ($this->options[XML_UNSERIALIZER_OPTION_GUESS_TYPES] === true) {
+                $guessType = true;
+            } else {
+                $guessType = false;
+            }
+        }
+
+        if ($this->options[XML_UNSERIALIZER_OPTION_DECODE_FUNC] !== null) {
+            $attribs = array_map($this->options[XML_UNSERIALIZER_OPTION_DECODE_FUNC], $attribs);
+        }
+        
+        $this->_depth++;
+        $this->_dataStack[$this->_depth] = null;
+
+        if (is_array($this->options[XML_UNSERIALIZER_OPTION_TAG_MAP]) && isset($this->options[XML_UNSERIALIZER_OPTION_TAG_MAP][$element])) {
+            $element = $this->options[XML_UNSERIALIZER_OPTION_TAG_MAP][$element];
+        }
+
+        $val = array(
+                     'name'         => $element,
+                     'value'        => null,
+                     'type'         => $type,
+                     'guessType'    => $guessType,
+                     'childrenKeys' => array(),
+                     'aggregKeys'   => array()
+                    );
+
+        if ($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE] == true && (count($attribs) > 0)) {
+            $val['children'] = array();
+            $val['type']  = $this->_getComplexType($element);
+            $val['class'] = $element;
+
+            if ($this->options[XML_UNSERIALIZER_OPTION_GUESS_TYPES] === true) {
+            	$attribs = $this->_guessAndSetTypes($attribs);
+            }            
+            if ($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY] != false) {
+                $val['children'][$this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY]] = $attribs;
+            } else {
+                foreach ($attribs as $attrib => $value) {
+                    $val['children'][$this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTES_PREPEND].$attrib] = $value;
+                }
+            }
+        }
+
+        $keyAttr = false;
+        
+        if (is_string($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY])) {
+            $keyAttr = $this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY];
+        } elseif (is_array($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY])) {
+            if (isset($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY][$element])) {
+                $keyAttr = $this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY][$element];
+            } elseif (isset($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY]['#default'])) {
+                $keyAttr = $this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY]['#default'];
+            } elseif (isset($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY]['__default'])) {
+                // keep this for BC
+                $keyAttr = $this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY]['__default'];
+            }
+        }
+        
+        if ($keyAttr !== false && isset($attribs[$keyAttr])) {
+            $val['name'] = $attribs[$keyAttr];
+        }
+
+        if (isset($attribs[$this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_CLASS]])) {
+            $val['class'] = $attribs[$this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_CLASS]];
+        }
+
+        array_push($this->_valStack, $val);
+    }
+
+   /**
+    * Try to guess the type of several values and
+    * set them accordingly
+    *
+    * @access   private
+    * @param    array      array, containing the values
+    * @return   array      array, containing the values with their correct types 
+    */
+    function _guessAndSetTypes($array)
+    {
+        foreach ($array as $key => $value) {
+        	$array[$key] = $this->_guessAndSetType($value);
+        }
+        return $array;
+    }
+    
+   /**
+    * Try to guess the type of a value and
+    * set it accordingly
+    *
+    * @access   private
+    * @param    string      character data
+    * @return   mixed       value with the best matching type
+    */
+    function _guessAndSetType($value)
+    {
+        if ($value === 'true') {
+            return true;
+        }
+        if ($value === 'false') {
+            return false;
+        }
+        if ($value === 'NULL') {
+            return null;
+        }
+        if (preg_match('/^[-+]?[0-9]{1,}$/', $value)) {
+        	return intval($value);
+        }
+        if (preg_match('/^[-+]?[0-9]{1,}\.[0-9]{1,}$/', $value)) {
+        	return doubleval($value);
+        }
+        return (string)$value;
+    }
+    
+   /**
+    * End element handler for XML parser
+    *
+    * @access private
+    * @param  object XML parser object
+    * @param  string
+    * @return void
+    */
+    function endHandler($parser, $element)
+    {
+        $value = array_pop($this->_valStack);
+        switch ($this->options[XML_UNSERIALIZER_OPTION_WHITESPACE]) {
+            case XML_UNSERIALIZER_WHITESPACE_KEEP:
+                $data = $this->_dataStack[$this->_depth];
+                break;
+            case XML_UNSERIALIZER_WHITESPACE_NORMALIZE:
+                $data = trim(preg_replace('/\s\s+/m', ' ', $this->_dataStack[$this->_depth]));
+                break;
+            case XML_UNSERIALIZER_WHITESPACE_TRIM:
+            default:
+                $data  = trim($this->_dataStack[$this->_depth]);
+                break;
+        }
+
+        // adjust type of the value
+        switch(strtolower($value['type'])) {
+
+            // unserialize an object
+            case 'object':
+                if (isset($value['class'])) {
+                    $classname  = $value['class'];
+                } else {
+                    $classname = '';
+                }
+                // instantiate the class
+                if ($this->options[XML_UNSERIALIZER_OPTION_TAG_AS_CLASSNAME] === true && class_exists($classname)) {
+                    $value['value'] = &new $classname;
+                } else {
+                    $value['value'] = &new $this->options[XML_UNSERIALIZER_OPTION_DEFAULT_CLASS];
+                }
+                if (trim($data) !== '') {
+                    if ($value['guessType'] === true) {
+                    	$data = $this->_guessAndSetType($data);
+                    }
+                    $value['children'][$this->options[XML_UNSERIALIZER_OPTION_CONTENT_KEY]] = $data;
+                }
+
+                // set properties
+                foreach ($value['children'] as $prop => $propVal) {
+                    // check whether there is a special method to set this property
+                    $setMethod = 'set'.$prop;
+                    if (method_exists($value['value'], $setMethod)) {
+                        call_user_func(array(&$value['value'], $setMethod), $propVal);
+                    } else {
+                        $value['value']->$prop = $propVal;
+                    }
+                }
+                //  check for magic function
+                if (method_exists($value['value'], '__wakeup')) {
+                    $value['value']->__wakeup();
+                }
+                break;
+
+            // unserialize an array
+            case 'array':
+                if (trim($data) !== '') {
+                    if ($value['guessType'] === true) {
+                    	$data = $this->_guessAndSetType($data);
+                    }
+                    $value['children'][$this->options[XML_UNSERIALIZER_OPTION_CONTENT_KEY]] = $data;
+                }
+                if (isset($value['children'])) {
+                    $value['value'] = $value['children'];
+                } else {
+                    $value['value'] = array();
+                }
+                break;
+
+            // unserialize a null value
+            case 'null':
+                $data = null;
+                break;
+
+            // unserialize a resource => this is not possible :-(
+            case 'resource':
+                $value['value'] = $data;
+                break;
+
+            // unserialize any scalar value
+            default:
+                if ($value['guessType'] === true) {
+                    $data = $this->_guessAndSetType($data);
+                } else {
+                    settype($data, $value['type']);
+                }
+            
+                $value['value'] = $data;
+                break;
+        }
+        $parent = array_pop($this->_valStack);
+        if ($parent === null) {
+            $this->_unserializedData = &$value['value'];
+            $this->_root = &$value['name'];
+            return true;
+        } else {
+            // parent has to be an array
+            if (!isset($parent['children']) || !is_array($parent['children'])) {
+                $parent['children'] = array();
+                if (!in_array($parent['type'], array('array', 'object'))) {
+                    $parent['type'] = $this->_getComplexType($parent['name']);
+                    if ($parent['type'] == 'object') {
+                        $parent['class'] = $parent['name'];
+                    }
+                }
+            }
+
+            if (in_array($element, $this->options[XML_UNSERIALIZER_OPTION_IGNORE_KEYS])) {
+                $ignoreKey = true;
+            } else {
+            	$ignoreKey = false;
+            }
+            
+            if (!empty($value['name']) && $ignoreKey === false) {
+                // there already has been a tag with this name
+                if (in_array($value['name'], $parent['childrenKeys']) || in_array($value['name'], $this->options[XML_UNSERIALIZER_OPTION_FORCE_ENUM])) {
+                    // no aggregate has been created for this tag
+                    if (!in_array($value['name'], $parent['aggregKeys'])) {
+                        if (isset($parent['children'][$value['name']])) {
+                            $parent['children'][$value['name']] = array($parent['children'][$value['name']]);
+                        } else {
+                            $parent['children'][$value['name']] = array();
+                        }
+                        array_push($parent['aggregKeys'], $value['name']);
+                    }
+                    array_push($parent['children'][$value['name']], $value['value']);
+                } else {
+                    $parent['children'][$value['name']] = &$value['value'];
+                    array_push($parent['childrenKeys'], $value['name']);
+                }
+            } else {
+                array_push($parent['children'], $value['value']);
+            }
+            array_push($this->_valStack, $parent);
+        }
+
+        $this->_depth--;
+    }
+
+   /**
+    * Handler for character data
+    *
+    * @access private
+    * @param  object XML parser object
+    * @param  string CDATA
+    * @return void
+    */
+    function cdataHandler($parser, $cdata)
+    {
+        if ($this->options[XML_UNSERIALIZER_OPTION_DECODE_FUNC] !== null) {
+            $cdata = call_user_func($this->options[XML_UNSERIALIZER_OPTION_DECODE_FUNC], $cdata);
+        }
+        $this->_dataStack[$this->_depth] .= $cdata;
+    }
+
+   /**
+    * get the complex type, that should be used for a specified tag
+    *
+    * @access   private
+    * @param    string      name of the tag
+    * @return   string      complex type ('array' or 'object')
+    */
+    function _getComplexType($tagname)
+    {
+        if (is_string($this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE])) {
+        	return $this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE];
+        }
+        if (isset($this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE][$tagname])) {
+        	return $this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE][$tagname];
+        }
+        if (isset($this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE]['#default'])) {
+        	return $this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE]['#default'];
+        }
+        return 'array';
+    }
+    
+   /**
+    * create the XML_Parser instance
+    *
+    * @access    private
+    * @return    boolean
+    */
+    function _createParser()
+    {
+        if (is_object($this->_parser)) {
+            $this->_parser->free();
+            unset($this->_parser);
+        }
+        $this->_parser = &new XML_Parser($this->options[XML_UNSERIALIZER_OPTION_ENCODING_SOURCE], 'event', $this->options[XML_UNSERIALIZER_OPTION_ENCODING_TARGET]);
+        $this->_parser->folding = false;
+        $this->_parser->setHandlerObj($this);
+        return true;
+    }
+}
+?>

Added: freepbx-modules/trunk/modules/core/agi-bin/checksound.agi
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/agi-bin/checksound.agi?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/agi-bin/checksound.agi (added)
+++ freepbx-modules/trunk/modules/core/agi-bin/checksound.agi Mon Apr  7 13:18:05 2008
@@ -1,0 +1,67 @@
+#!/usr/bin/php -q
+<?php 
+
+// Copyright (C) 2007 Atengo LLC
+//
+// 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.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+
+/* --------WARNING---------
+ * 
+ * This script is auto-copied from an included module and will get overwritten.
+ * If you modify it, you must change it to write only, in the agi-bin directory,
+ * to keep it from getting changed.
+ */
+
+/**	This function is to replace the following command, which attempts to check if a wav
+ *	file is present. At the time of writing, Asterisk had a bug that would return
+ *  bogus SYSTEMSTATUS results. This script is written to use the SYSTEMSTATUS variable
+ *  for now so that it may no longer be necessary when that command is functioning.
+ *
+ *	exten => vmx,n,TrySystem(/bin/ls ${ASTSPOOLDIR}/voicemail/${VMCONTEXT}/${ARG1}/${MODE}.[wW][aA][vV])
+ */
+
+require_once "phpagi.php";
+
+$AGI = new AGI();
+$file		= $argv[1];
+
+if (file_exists($file.".wav") || file_exists($file.".WAV")) {
+	$AGI->set_variable('SYSTEMSTATUS','SUCCESS');
+} else {
+	$AGI->set_variable('SYSTEMSTATUS','APPERROR');
+	debug("VmX requires: $file.wav or .WAV exist in order to function",1);
+}
+
+// EOF dialparties.agi
+exit( 0 );
+
+// helper functions
+function get_var( $agi, $value)
+{
+	$r = $agi->get_variable( $value );
+	
+	if ($r['result'] == 1)
+	{
+		$result = $r['data'];
+		return $result;
+	}
+	else
+		return '';
+}
+
+function debug($string, $level=3)
+{
+	global $AGI;
+	$AGI->verbose($string, $level);
+}
+
+?>

Propchange: freepbx-modules/trunk/modules/core/agi-bin/checksound.agi
------------------------------------------------------------------------------
    svn:executable = *

Added: freepbx-modules/trunk/modules/core/agi-bin/dialparties.agi
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/agi-bin/dialparties.agi?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/agi-bin/dialparties.agi (added)
+++ freepbx-modules/trunk/modules/core/agi-bin/dialparties.agi Mon Apr  7 13:18:05 2008
@@ -1,0 +1,676 @@
+#!/usr/bin/php -q
+<?php 
+
+// Copyright (C) 2003 Zac Sprackett <zsprackett-asterisk at sprackett.com>
+//
+// 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.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Amended by Coalescent Systems Inc. Sept, 2004
+// to include support for DND, Call Waiting, and CF to external trunk
+// info at coalescentsystems.ca
+// 
+// This script has been ported to PHP by 
+// Diego Iastrubni <diego.iastrubni at xorcom.com> and the FreePBX community
+
+/* --------WARNING---------
+ * 
+ * This script is auto-copied from an included module and will get overwritten.
+ * If you modify it, you must change it to write only, in the agi-bin directory,
+ * to keep it from getting changed.
+ */
+
+require_once "phpagi.php";
+require_once "phpagi-asmanager.php";
+
+$ext      = array();		// Hash that will contain our list of extensions to call
+$ext_hunt = array();		// Hash that will contain our list of extensions to call used by huntgroup
+$cidnum   = "";		// Caller ID Number for this call
+$cidname  = "";		// Caller ID Name for this call
+$timer    = "";		// Call timer for Dial command
+$dialopts = "";		// options for dialing
+$rc       = "";		// Catch return code
+$priority = "";		// Next priority 
+$rgmethod = "";		// If Ring Group what ringing method was chosen
+$dsarray  = array();	// This will hold all the dial strings, used to check for duplicate extensions
+
+$AGI = new AGI();
+debug("Starting New Dialparties.agi", 1);
+
+// Get required channels variables that used to come from amportal.conf
+$ampmgruser  = get_var( $AGI, "AMPMGRUSER" );
+$ampmgrpass  = get_var( $AGI, "AMPMGRPASS" );
+$cwinusebusy = get_var( $AGI, "CWINUSEBUSY" );
+
+$astman = new AGI_AsteriskManager( );	
+if (!$astman->connect("127.0.0.1", $ampmgruser , $ampmgrpass)) {
+	exit (1);
+}
+
+$priority = get_var( $AGI, "priority" ) + 1;
+
+// Caller ID info is stored in $request in AGI class, passed from Asterisk
+$cidnum = $AGI->request['agi_callerid'];
+$cidname = $AGI->request['agi_calleridname'];
+debug("Caller ID name is '$cidname' number is '$cidnum'", 1);
+
+// From this point forward, Set KEEPCID in the channel so subsequent calls, CF, etc. retain the incoming
+// CID that get sent down channel local.
+$AGI->set_variable('__KEEPCID','TRUE');
+
+// Set to '' in case it was previously set
+//
+$AGI->set_variable('DIALSTATUS_CW','');						
+
+$timer		= get_var( $AGI, "ARG1" );
+$dialopts	= get_var( $AGI, "ARG2" );
+$rgmethod	= get_var( $AGI, "RingGroupMethod" );
+
+$alertinfo = get_var( $AGI, "ALERT_INFO" );
+if ($alertinfo) {
+	debug("Setting Alert-Info:  $alertinfo", 4);
+	$AGI->set_alertinfo($alertinfo);						
+}
+
+$sippheader = get_var( $AGI, "SIPADDHEADER" );
+if ($sippheader) {
+	$fields = explode(':',$sippheader,2);
+	debug("Setting sipheader ".$fields[0].": ".$fields[1], 4);
+	$AGI->exec_sipaddheader($fields[0], $fields[1]);
+}
+
+/* TODO: this does not work but should, moved to macro-dial for now
+ *
+$mohclass = get_var( $AGI, "MOHCLASS" );
+if ($mohclass) {
+	debug("Setting MoH Class:  $mohclass", 4);
+	$AGI->set_music(true, $mohclass);						
+}
+ */
+
+$pr_dialstatus	= get_var( $AGI, "PR_DIALSTATUS" );
+
+$fmgrp  = get_var( $AGI, "FMGRP" );
+$nodest	= get_var( $AGI, "NODEST" );
+if (empty($nodest))	$nodest	= '';
+
+$ringgroup_index	= get_var( $AGI, "RINGGROUP_INDEX" );
+$use_confirmation	= get_var( $AGI, "USE_CONFIRMATION" );
+if (empty($use_confirmation))	$use_confirmation = "FALSE";
+debug("USE_CONFIRMATION:  '$use_confirmation'", 5);
+debug("RINGGROUP_INDEX:   '$ringgroup_index'", 5);
+
+if (empty($timer))	$timer		= 0;
+if (empty($dialopts))	$dialopts	= "";
+if (empty($rgmethod))	$rgmethod	= "none";
+
+debug("Methodology of ring is  '$rgmethod'", 1);
+
+// reset the ringgroup method to its fundamental algorithm and pull out if
+// master mode.
+
+$recall_mastermode=$rgmethod;
+
+switch ($rgmethod) {
+	case 'ringall-prim':
+		$rgmethod	= "ringall";
+		$mastermode	= 1;
+		break;
+	case 'hunt-prim':
+		$rgmethod	= "hunt";
+		$mastermode	= 1;
+		break;
+	case 'memoryhunt-prim':
+		$rgmethod	= "memoryhunt";
+		$mastermode	= 1;
+		break;
+	case 'ringallv2-prim':
+		$rgmethod = "ringallv2";
+		$mastermode = 1;
+		break;
+	default:
+		$mastermode	= 0;
+		$pr_dialstatus = ""; // not relevant if not mastermode, clear it so dnd doesn't propagate, and other
+}
+
+// call confirmation only works with ringall and ringall-prim. The javascripts in ringgroups
+// and follow-me should enforce this. If that has been overridden then force ringall.
+// Keep this code after the matermode check above, since they will at least get mastermode
+// if they set a -prim mode in one of the others
+//
+if ( ($use_confirmation != "FALSE") && (trim($rgmethod) != "ringall") && (trim($rgmethod) != "ringallv2") ) {
+	debug("Unsupported RingMethod: '$rgmethod' resetting to ringall", 1);
+	$rgmethod	= "ringall";
+}
+
+// Start with Arg Count set to 3 as two args are used
+$arg_cnt = 3;
+while($arg = get_var($AGI,"ARG". $arg_cnt)) {
+	// not sure why, dialparties will get stuck in a loop if noresponse
+	if ($arg == '-') {
+		debug("get_variable got a \"noresponse\"!  Exiting",3);
+		exit($arg_cnt);
+	}
+	$extarray = split( '-', $arg );
+	foreach ( $extarray as $k ) {
+		$ext[] = $k;
+		debug("Added extension $k to extension map", 3);
+	}
+	$arg_cnt++;
+}
+
+// FollowMe Preparation for Pre-Ring:
+//
+// If the primary extension is in the ringgroup list, then it should be rung
+// during both the pre-ring time and the list time, so it's real prering time
+// is the entire time. If it is not in the list, then it should only ring
+// for the pre-ring time. This section determines the times and then adds it
+// to the list if not already there, so that the dialstring is computed
+// appropriately. This section also makes sure that the primary extension
+// is at the top of the list.
+//
+// Notes before I forget. The primary may have been in the list and screwed
+// above. So ... do I need to move this up, probably.
+//
+if ($rgmethod == "ringallv2" && $fmgrp != "") {
+
+	$fmgrp_primaryremoved = 0;
+
+	$fmgrp_prering  = $AGI->database_get('AMPUSER', $fmgrp."/followme/prering"); 
+	$fmgrp_prering  = $fmgrp_prering['data'] > 1 ? $fmgrp_prering['data'] : 2;
+		 
+	$fmgrp_grptime  = $AGI->database_get('AMPUSER', $fmgrp."/followme/grptime"); 
+	$fmgrp_grptime  = $fmgrp_grptime['data'];
+	debug("got fmgrp_prering: $fmgrp_prering, fmgrp_grptime: $fmgrp_grptime",4);
+
+	$fmgrp_totalprering = $fmgrp_grptime + $fmgrp_prering;
+	debug("fmgrp_totalprering: $fmgrp_totalprering",4);
+
+	if (in_array($fmgrp, $ext)) {
+		debug("found extension in pre-ring and array",4);
+		$fmgrp_realprering = $fmgrp_totalprering;
+		if ($ext[0] != $fmgrp) {
+			$tmpx=array_flip($ext);
+			unset($ext[$tmpx[$fmgrp]]);
+			array_unshift($ext,$fmgrp);
+		}
+	}	else {
+		debug("extension not in group list, ringging only during perring time",4);
+		$fmgrp_realprering = $fmgrp_prering;
+		array_unshift($ext,$fmgrp);
+	}
+	debug("ringallv2 ring times: REALPRERING: $fmgrp_realprering, PRERING: $fmgrp_prering",4);
+}
+
+// IF THE FIRST EXTENSION IS CALL FORWARD ENABLED (put in logic) then we don't do master mode
+// which means we reset the flag here after detecting that and just say we are not in master
+// mode and all is well. That means the loop below needs to be modified to detect the first
+// extension and do this if the case.
+
+// Check for call forwarding first
+// If call forward is enabled, we use chan_local
+// Hacky. We should be using an associative array, shouldn't we?
+$count = 0;
+foreach( $ext as $k) {
+	$cf  = $AGI->database_get('CF',$k);
+	$cf  = $cf['data'];
+	if (strlen($cf)) {
+		// append a hash sign so we can send out on chan_local below.
+		$ext[$count] = $cf.'#';  
+		debug("Extension $k has call forward set to $cf", 1);
+
+		// if this is the primary extension and CF enabled, then cancel mastermode
+		// whether it is or not, no need to check.
+		//
+		if ($count == 0) {
+			$mastermode = 0;
+			$pr_dialstatus = ""; // not relevant if not mastermode, clear it so dnd doesn't propagate, and other
+			debug("Primary ext is CF so disabling mastermode if it was set", 4);
+		}
+	}
+	else {
+		debug("Extension $k cf is disabled", 3);
+	}
+	$count++;
+}
+
+// IF DND AND we process it as a DND (no CF enabled) then we need to some how flag that ALL THE REST
+// should now be ignored and not processed if in master mode (and this primary). Do this by setting some
+// sort of flag that says master mode DND so skip everything else below (set them all to "").
+//
+
+// Hacky.
+$count = 0;
+$dndprimary = 0;
+// Now check for DND
+foreach ( $ext as $k ) {
+	if ( (strpos($k,"#")==0) ) {
+		// no point in doing if cf is enabled
+		$dnd = $AGI->database_get('DND',$k);
+		$dnd = $dnd['data'];
+		if (strlen($dnd) || $pr_dialstatus == "BUSY") {
+			debug("Extension $k has do not disturb enabled, or followme pre-ring returned busy", 2);
+			unset($ext[$count]);
+			$AGI->set_variable('DIALSTATUS','BUSY');						
+			// if this is primary set dndprimary and figure out if needed below
+			//
+			if ($count == 0 && $mastermode) {
+				$dndprimary = 1;
+				debug("Primary extension is DND, so if mastermode, all should be dnd", 4);
+			}
+			if ($count == 0) {
+				$fmgrp_primaryremoved = 1;
+			}
+		} 
+		else {
+			debug("Extension $k do not disturb is disabled", 3);
+		}
+	}
+	$count++;
+}
+
+// Main calling loop
+//
+$skipremaining = 0; // used to allow primary to ring but skip the rest
+$ds = '';
+foreach ( $ext as $k ) {
+	// mastermode description:
+	//
+	// if mastermode is set then the first extension will be examined and mastermode will be reset so that the others
+	// are left alone. If the remaining extensions are not to be tried, skpremaining will be set to 1 which will
+	// result in dndprimary being set to 1 thus diabling the remaining list.
+	//
+	// if cf unconditional was already detected on the primary, then mastermode will have been reset at this point
+	// since that will negate the mastermode concpet.
+	//
+	// if dnd was set on the primary then dndprimary will already be set resulting in a completly blanked out list
+	// since dnd on the primary means don't bother me on any.
+
+	// Don't bother checking these if we will be blanking the extnum anyhow
+	if ($skipremaining == 1) {
+		$dndprimary = 1;
+	}
+	if ($dndprimary == 0) {
+		// TODO what are these comments...? do we need to remove them...?
+		$extnum    = $k;
+		$exthascw  = $AGI->database_get('CW', $extnum);// ? 1 : 0;
+		$exthascw  = $exthascw['data']? 1:0;
+		$extcfb    = $AGI->database_get('CFB', $extnum);//? 1 : 0;
+		$extcfb    = $extcfb['data'];
+		$exthascfb = (strlen($extcfb) > 0) ? 1 : 0;
+		$extcfu    = $AGI->database_get('CFU', $extnum);// ? 1 : 0;
+		$extcfu    = $extcfu['data'];
+ 		$exthascfu = (strlen($extcfu) > 0) ? 1 : 0;
+	
+		// Dump details in level 4
+		debug("extnum $extnum has:  cw: $exthascw; hascfb: $exthascfb [$extcfb] hascfu: $exthascfu [$extcfu]",4);
+
+		// check if mastermode and then reset here. If mastermode, this will be the first extension so
+		// the state is checked and a decision is made as to what to do. We have gotten all the cf variables
+		// above. If CF unconditional was set, we never get here because we alread reset mastermode. If DND
+		// were set then we never get here becasue didprimary was set
+		if ($mastermode == 1) {
+			$mastermode = 0;
+			$extstate = is_ext_avail($extnum);
+			debug("Extension $extnum has ExtensionState: $extstate",1);
+
+			if ( ($exthascw == 1) && ($extstate == 1) ) {
+				// process this one extension but the remaining should be skipped since there is cw and
+				// the extension is occupied. This will try this extension but not the others.
+				$skipremaining = 1;
+				debug("In mastermode with cw enabled so $extnum will be tried and others skipped",4);
+			} elseif ( ($exthascw == 0) && ($extstate == 1) ) {
+				// no cw, ext is busy. So if cfb is set, it will forward there and if not, it will be
+				// ignored as normal behavior. In either case, we skip the remaining numbers.
+				$skipremaining = 1;
+				debug("In mastermode with cw disabled so $extnum will be processed in case cfb set",4);
+			}
+			// All other cases should act like normal. Unavailable, not busy, ringing, etc.
+			// should not be effected
+		}
+	} // end if ($dndprimary == 0)
+	// $dndprimary == 1 so clear the extension
+	else {
+		// clear the current extension if dndprimary has been set. This will only be the case if in mastermode so no need to check
+		// that. Use this to skip remaining extensions also if just ringing the primary.
+		$extnum = '';
+	}
+
+	// if CF is not in use and $dndprimary is not set otherwise $extnum has been cleared and nothing to do
+	//
+	if ( (strpos($k,"#")==0) && $dndprimary == 0) {
+		// CW is not in use or CFB is in use on this extension, then we need to check!
+		if ( ($exthascw == 0) || ($exthascfb == 1) || ($exthascfu == 1) ) {
+			// get ExtensionState: 0-idle; 1-busy; 4-unavail; 8-ringing <--- these are unconfirmed
+			$extstate = is_ext_avail($extnum);
+			debug("Extension $extnum has ExtensionState: $extstate",1);
+	
+			// Ext has CFU and is Unavailable
+			if ( ($exthascfu == 1) && ($extstate == 4) ) {
+				// If part of a ring group, then just do what CF does, otherwise needs to
+				// drop back to dialplan with NOANSWER
+				if ($rgmethod != '' && $rgmethod != 'none') {
+					debug("Extension $extnum has call forward on no answer set and is unavailable and is part of a Ring Group forwarding to '$extcfu'",1);
+					$extnum = $extcfu . '#';   # same method as the normal cf, i.e. send to Local
+				} else {
+					debug("Extension $extnum has call forward on no answer set and is unavailable",1);
+					$extnum = '';
+					$AGI->set_variable('DIALSTATUS','NOANSWER');
+				}
+			} elseif ( ($exthascw == 0) || ($exthascfb == 1) ) {
+				debug("Checking CW and CFB status for extension $extnum",3);
+				// extension in use
+				if ($extstate > 0 && $extstate != 4) {
+					debug("Extension $extnum is not available to be called", 1);
+					// extension in use
+					if ($exthascfb == 1) {
+						debug("Extension $extnum has call forward on busy set to $extcfb",1);
+						$extnum = $extcfb . '#';   # same method as the normal cf, i.e. send to Local
+					// CW not in use
+					} elseif ($exthascw == 0) {
+						debug("Extension $extnum has call waiting disabled",1);
+						$extnum = '';
+						$AGI->set_variable('DIALSTATUS','BUSY');						
+					} else {
+						debug("Extension $extnum has call waiting enabled",1);
+					}
+				}
+			// -1 means couldn't read status usually due to missing HINT
+			} elseif ($extstate < 0) {
+				debug("ExtensionState for $extnum could not be read...assuming ok",3);
+			} else {
+				debug("Extension $extnum is available",1);
+			}
+		} elseif ($rgmethod == "none" && $exthascw == 1 && $cwinusebusy) {
+			$extstate = is_ext_avail($extnum);
+			if ($extstate == 1) {
+				$AGI->set_variable('DIALSTATUS_CW','BUSY');						
+				debug("Extension $extnum has call waiting enabled with state: $extstate",1);
+			}
+		// get ExtensionState: 0-idle; 1-busy; 4-unavail; 8-ringing <--- these are unconfirmed
+		} elseif ( ($exthascw == 1) && ($rgmethod == 'firstnotonphone') ) {
+			$extstate = is_ext_avail($extnum);
+			debug("Extension $extnum has ExtensionState: $extstate",1);
+			// CW in use - but blocked for hunt
+			if ($extstate == 1) {
+				debug("Extension $extnum has call waiting enabled but blocked for hunt",1);
+				$extnum = '';
+				$AGI->set_variable('DIALSTATUS','BUSY');	
+			}
+		}
+	}
+	
+	if ($extnum != '') {
+		// Still got an extension to be called?
+		// check if we already have a dial string for this extension
+		// if so, ignore it as it's pointless ringing it twice !
+		$realext = str_replace("#", "", $extnum);
+		if ( isset($dsarray[$realext]) ) {
+			debug("Extension '$realext' already in the dialstring, ignoring duplicate",1);
+		} else {
+			$dsarray[$realext] = 1;  // could be dial string i suppose but currently only using for duplicate check
+			$extds = get_dial_string( $AGI, $extnum, $use_confirmation, $ringgroup_index);
+			if (strlen($extds)) {
+			 	$ds .= $extds . '&';
+			}
+			// Update Caller ID for calltrace application
+			if ((strpos($k,"#")==0) && (($rgmethod != "hunt") && ($rgmethod != "memoryhunt") && ($rgmethod != "firstavailable") && ($rgmethod != "firstnotonphone")) ) {
+				if ( isset($cidnum) && is_numeric($cidnum) ) {
+					$rc = $AGI->database_put('CALLTRACE', $k, $cidnum);
+					if ($rc['result'] == 1) {
+						debug("dbset CALLTRACE/$k to $cidnum", 3);
+					} else {
+						debug("Failed to DbSet CALLTRACE/$k to $cidnum ({$rc['result']})", 1);
+					}
+				} else {
+					// We don't care about retval, this key may not exist
+					$AGI->database_del('CALLTRACE', $k);
+					debug("DbDel CALLTRACE/$k - Caller ID is not defined", 3);
+				}
+			} else {
+				$ext_hunt[$k]=$extds; // Need to have the extension HASH set with technology for hunt group ring 
+			}
+		}
+	}
+} // end foreach ( $ext as $k )
+
+$dshunt		= '';
+$loops		= 0;
+$myhuntmember	= "";
+
+if (($rgmethod == "hunt") || ($rgmethod == "memoryhunt") || ($rgmethod == "firstavailable") || ($rgmethod == "firstnotonphone")) {
+	if ($cidnum) {
+		$AGI->set_variable('CALLTRACE_HUNT',$cidnum);
+	}
+	foreach ($extarray as $k ) {
+		// we loop through the original array to get the extensions in order of importance
+		if ($ext_hunt[$k]) {
+			//If the original array is included in the extension hash then set variables
+			$myhuntmember="HuntMember"."$loops";
+			if (($rgmethod == "hunt") || ($rgmethod == "firstavailable") || ($rgmethod == "firstnotonphone")) {
+				$AGI->set_variable($myhuntmember,$ext_hunt[$k]);
+			} elseif ($rgmethod == "memoryhunt") {
+				if ($loops==0) {
+					$dshunt =$ext_hunt[$k];
+				} else {
+					$dshunt .='&'.$ext_hunt[$k];
+				}
+				$AGI->set_variable($myhuntmember,$dshunt);
+			}
+			$loops += 1;
+		}
+	}
+}
+
+$ds = chop($ds," &");
+
+if ($nodest != '' && $use_confirmation == 'FALSE') {
+	if (strpos($dialopts,"M(auto-blkvm)") > 0  || strpos($dialopts,"M(auto-blkvm)") === 0 ||
+	    strpos($dialopts,"M(auto-confirm") > 0 || strpos($dialopts,"M(auto-confirm") === 0 ||
+	    strpos($dialopts,"M(confirm") > 0      || strpos($dialopts,"M(confirm") === 0) {
+		debug("NODEST: $nodest blkvm enabled macro already in dialopts: $dialopts",4);
+	} else {
+		$dialopts .= "M(auto-blkvm)";
+		debug("NODEST: $nodest adding M(auto-blkvm) to dialopts: $dialopts",4);
+	}
+}
+
+// FollowMe Changes:
+//
+// We need to determine if the generated dialstring can be dialed as is. This will be the case if there are no
+// or is only a single extension to dial. 
+//
+// First, unset any blank fields so we know how many extensions there are to call.
+//
+// If mastermode (skipremaining == 1) was triggered then we just set the ringtime to what the primary extension
+// should ring for and let this dialstring go.
+//
+// If there is only one extension in the list, then we need to determine how long to ring it (depending on if it
+// was the primary or another extension, then let the generated dialstring ring it.
+//
+// Otherwise, we need to re-create the dialstring to be processed by our special dialplan that will ring the
+// primary extension and hold the group list for the required delay. Also - if we are in a call confirmation mode
+// then we need to reset the call confirm variables with one level of inheritance so that they remain in the new
+// channels but don't get further propogated after that. We also clear it for the remainder of this instance since
+// we are not yet triggering further actions until the next call.
+//
+// Notes: $fmgrp_primaryremoved is set to 1 if the primary has been removed from the list so we know that it was dnd-ed.
+//        this only matters in non-prim mode, where we need to know if the remaining list contains the primary extension
+//        or not.
+//
+if ($rgmethod == 'ringallv2') {
+	$count = 0;
+	foreach ($ext as $x) {
+		if ($x == '') {
+			unset($ext[$count]);
+		}
+		$count++;
+	}
+
+	if (($skipremaining == 1) || (count($ext) == 1 && $fmgrp_primaryremoved == 0)) {
+		$timer = $fmgrp_realprering;
+	} elseif (count($ext) == 1 && $fmgrp_primaryremoved == 1) {
+		$timer = $fmgrp_grptime;
+	} elseif (count($ext) == 1) {
+		$timer = $fmgrp_totalprering; // not sure what would trigger this ?
+	} else {
+		$timer = $fmgrp_totalprering; 
+		$ds = "Local/FMPR-".array_shift($ext)."@from-internal&Local/FMGL-".implode('-',$ext)."@from-internal";
+
+		$fmgrp_fmunique = $AGI->request['agi_channel'];
+		$AGI->set_variable('_FMUNIQUE',$fmgrp_fmunique);						
+		$AGI->set_variable('_RingGroupMethod',"ringall");						
+		$fmgrp_prering -= 2;
+		$AGI->set_variable('_FMPRERING',$fmgrp_prering);						
+		$AGI->set_variable('_FMREALPRERING',$fmgrp_realprering);						
+		$AGI->set_variable('_FMGRPTIME',$fmgrp_grptime);						
+		$AGI->set_variable('_FMPRIME',($recall_mastermode == "ringallv2")?"FALSE":"TRUE");						
+
+		debug("FMUNIQUE: $fmgrp_fmunique, FMRERING: $fmgrp_prering, FMREALPRERING: $fmgrp_realprering, FMGRPTIME: $fmgrp_grptime",6);
+
+		if ($use_confirmation != 'FALSE') {
+			$AGI->set_variable('_USE_CONFIRMATION',$use_confirmation);						
+			$AGI->set_variable('_RINGGROUP_INDEX',$ringgroup_index);						
+			$use_confirmation = 'FALSE';
+		}
+	}
+}
+
+if ($nodest != '' && $use_confirmation == 'FALSE') {
+	if (strpos($dialopts,"M(auto-blkvm)") > 0  || strpos($dialopts,"M(auto-blkvm)") === 0 ||
+	    strpos($dialopts,"M(auto-confirm") > 0 || strpos($dialopts,"M(auto-confirm") === 0 ||
+	    strpos($dialopts,"M(confirm") > 0      || strpos($dialopts,"M(confirm") === 0) {
+		debug("NODEST: $nodest blkvm enabled macro already in dialopts: $dialopts",4);
+	} else {
+		$dialopts .= "M(auto-blkvm)";
+		debug("NODEST: $nodest adding M(auto-blkvm) to dialopts: $dialopts",4);
+	}
+}
+
+if (!strlen($ds)) {
+	$AGI->noop('');
+} else {
+	if (($rgmethod == "hunt") || ($rgmethod == "memoryhunt") || ($rgmethod == "firstavailable") || ($rgmethod == "firstnotonphone")) {
+		$ds = '|';
+		if ($timer) {
+			$ds .= $timer;
+		}
+		$ds .= '|' . $dialopts; // pound to transfer, provide ringing
+		$AGI->set_variable('ds',$ds);
+		$AGI->set_variable("HuntMembers",$loops);
+		$AGI->set_priority(20); // dial command is at priority 20 where dialplan handles calling a ringgroup with strategy of "hunt" or "MemoryHunt"
+	} else {
+		$ds .= '|';
+		if ($timer) {
+			$ds .= $timer;
+			if (trim($use_confirmation) != "FALSE") {
+				$AGI->set_variable('__RT',$timer);
+			}
+		}
+		$ds .= '|' . $dialopts; // pound to transfer, provide ringing
+		if (trim($use_confirmation) != "FALSE") {
+			$AGI->set_variable('__RG_IDX',$ringgroup_index);
+			if ( isset($cidnum) && is_numeric($cidnum) ) {
+				$AGI->set_variable('__CALLCONFIRMCID',$cidnum);
+			} else {
+				$AGI->set_variable('__CALLCONFIRMCID',"999");
+			}
+		}
+		$AGI->set_variable('ds',$ds);
+		$AGI->set_priority(10); // dial command is at priority 10
+	}
+}
+
+// sanity check make sure dialstatus is set to something
+//
+if (! $ds) {
+	$dialstatus  = get_var( $AGI, "DIALSTATUS" );
+	if (! $dialstatus) {
+		debug("Setting default NOANSWER DIALSTATUS since no extensions available",1);
+		$AGI->set_variable('DIALSTATUS','NOANSWER');
+	}
+}
+
+$astman->disconnect();
+
+// EOF dialparties.agi
+exit( 0 );
+
+// helper functions
+function get_var( $agi, $value) {
+	$r = $agi->get_variable( $value );
+	
+	if ($r['result'] == 1) {
+		$result = $r['data'];
+		return $result;
+	}
+	return '';
+}
+
+function get_dial_string( $agi, $extnum, $use_confirmation, $ringgroup_index ) {
+	$dialstring = '';
+	
+	if (strpos($extnum,'#') != 0) {
+		// "#" used to identify external numbers in forwards and callgourps
+		// If using call confirmation, need to put the # back into the new dialstring
+		// we then place all external calls (denoted with a # at the end) through
+		// the [grps] extension for the RINGGROUP_INDEX that was called. This
+		// triggers the call confirmation macro along with the required messages
+		// that were set.
+		//
+		$extnum = str_replace("#", "", $extnum);
+		if (trim($use_confirmation) == "FALSE") {
+			$dialstring = 'Local/'.$extnum.'@from-internal/n';
+		} else {
+			$dialstring = 'Local/RG-'.$ringgroup_index.'-'.$extnum.'#@from-internal';
+		}
+		debug("Built External dialstring component for $extnum: $dialstring", 4);
+	} else {
+		$device_str = sprintf("%s/device", $extnum);
+		$device = $agi->database_get('AMPUSER',$device_str);
+		$device = $device['data'];
+		
+		// a user can be logged into multipe devices, append the dial string for each		
+		$device_array = split( '&', $device );
+		foreach ($device_array as $adevice) {
+			if (trim($use_confirmation) == "FALSE") {
+				$dds = $agi->database_get('DEVICE',$adevice.'/dial');
+				$dialstring .= $dds['data'];
+				$dialstring .= '&';
+			} else {
+				$dialstring .= 'Local/LC-'.$adevice.'@from-internal&';
+			}
+		}
+		$dialstring = trim($dialstring," &");
+	}
+	return $dialstring;
+}
+
+function debug($string, $level=3) {
+	global $AGI;
+	$AGI->verbose($string, $level);
+}
+
+function mycallback( $rc ) {
+	debug("User hung up. (rc=" . $rc . ")", 1);
+	exit ($rc);
+}
+
+function is_ext_avail( $extnum ) {
+	global $astman;
+	
+	$status = $astman->ExtensionState( $extnum, 'from-internal' );
+		
+	$status = $status['Status'];
+	debug("ExtensionState: $status", 4);
+	return $status;
+}
+
+?>

Propchange: freepbx-modules/trunk/modules/core/agi-bin/dialparties.agi
------------------------------------------------------------------------------
    svn:executable = *

Added: freepbx-modules/trunk/modules/core/agi-bin/directory
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/agi-bin/directory?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/agi-bin/directory (added)
+++ freepbx-modules/trunk/modules/core/agi-bin/directory Mon Apr  7 13:18:05 2008
@@ -1,0 +1,520 @@
+#!/usr/bin/php -q
+<?php
+
+/**
+// AGI directory Copyright (C) 2005 Greg MacLellan (greg at mtechsolutions.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+
+*/
+
+/* --------WARNING---------
+ * 
+ * This script is auto-copied from an included module and will get overwritten.
+ * If you modify it, you must change it to write only, in the agi-bin directory,
+ * to keep it from getting changed.
+ */
+
+// set to 1 to say "zed" instead of "zee"
+define("SAY_ZED",0);
+
+/******************************************************************************/
+
+define("DEBUG", 0);
+
+define("DIR_LAST", 0);
+define("DIR_FIRST", 1);
+define("DIR_BOTH", 2);
+
+define("NUM_DIGITS", 3);
+define("MAX_REPEAT", 2); // how many times can we repeat the menu before hanging up?
+
+// ordinal values of digits
+define("D_0",48);
+define("D_1",49);
+define("D_2",50);
+define("D_3",51);
+define("D_4",52);
+define("D_5",53);
+define("D_6",54);
+define("D_7",55);
+define("D_8",56);
+define("D_9",57);
+define("D_POUND",35);
+define("D_STAR",42);
+
+include("phpagi.php");
+
+function get_var( $agi, $value)
+{
+	$r = $agi->get_variable( $value );
+	
+	if ($r['result'] == 1)
+	{
+		$result = $r['data'];
+		return $result;
+	}
+	else
+		return '';
+}
+
+function output(&$var) {
+	if (DEBUG) {
+		global $logfile;
+		
+		if (!isset($logfile)) return false;
+		
+		ob_start();
+		var_dump($var);
+		$output = ob_get_contents();
+		ob_end_clean();
+		fwrite($logfile, $output);
+	}
+}
+
+
+function parse_voicemailconf($filename, &$vmconf, &$section) {
+	if (is_null($vmconf)) {
+		$vmconf = array();
+	}
+	if (is_null($section)) {
+		$section = "general";
+	}
+	
+	if (file_exists($filename)) {
+		$fd = fopen($filename, "r");
+		while ($line = fgets($fd, 1024)) {
+			if (preg_match("/^\s*(\d+)\s*=>\s*(\d+),(.*),(.*),(.*),(.*)\s*([;#].*)?/",$line,$matches)) {
+				// "mailbox=>password,name,email,pager,options"
+				// this is a voicemail line	
+				$vmconf[$section][ $matches[1] ] = array("mailbox"=>$matches[1],
+									"pwd"=>$matches[2],
+									"name"=>$matches[3],
+									"email"=>$matches[4],
+									"pager"=>$matches[5],
+									);
+								
+				// parse options
+				foreach (explode("|",$matches[6]) as $opt) {
+					$temp = explode("=",$opt);
+					if (isset($temp[1])) {
+						list($key,$value) = $temp;
+						$vmconf[$section][ $matches[1] ]["options"][$key] = $value;
+					}
+				}
+			} else if (preg_match("/^\s*(\d+)\s*=>\s*dup,(.*)\s*([;#].*)?/",$line,$matches)) {
+				// "mailbox=>dup,name"
+				// duplace name line
+				$vmconf[$section][ $matches[1] ]["dups"][] = $matches[2];
+			} else if (preg_match("/^\s*#include\s+(.*)\s*([;#].*)?/",$line,$matches)) {
+				// include another file
+				
+				if ($matches[1][0] == "/") {
+					// absolute path
+					$filename = $matches[1];
+				} else {
+					// relative path
+					$filename =  dirname($filename)."/".$matches[1];
+				}
+				
+				parse_voicemailconf($filename, $vmconf, $section);
+				
+			} else if (preg_match("/^\s*\[(.+)\]/",$line,$matches)) {
+				// section name
+				$section = strtolower($matches[1]);
+			} else if (preg_match("/^\s*([a-zA-Z0-9-_]+)\s*=\s*(.*?)\s*([;#].*)?$/",$line,$matches)) {
+				// name = value
+				// option line
+				$vmconf[$section][ $matches[1] ] = $matches[2];
+			}
+		}
+	}
+}
+
+
+/** Play a bunch of files, optionally accepting input and looping
+ * @param $files		The file/files to play (for multiple files, pass array)
+ * @param $escape_digits	The DTMF tones that can be pressed & returned, ie, "123*"
+ * @param $timeout		The timeout waiting for a digit, or 0 to not wait at all.
+ * @param $max_digits		Maximum number of digits to get. **NOT IMPLEMENTED YET.. 1 only**
+ * @param $loop			False for no loop, or an integer >0 being the number of times to loop. 
+ * @param $loopreturn		Value to return when the loop expires
+*/
+function stream_multiple($files, $escape_digits = "", $timeout = 0, $max_digits = 1, $loop = false, $loopreturn = 0) {
+	global $agi;
+	
+	if (!is_array($files)) {
+		$files = array($files);
+	}
+	
+	$i = 0;
+	do {
+		foreach ($files as $file) {
+			$agi->verbose("-- Playing '".$file."' (language 'en')");
+			$r = $agi->stream_file($file, $escape_digits);
+			$agi->conlog("stream_multiple: $file returned ".$r["result"]);
+			switch ($r["result"]) {
+				case 0: // they did nothing
+				break;
+				case -1: // they hungup
+					$agi->verbose("remote user hungup");
+					return -1;
+				break;
+				default: // they pressed a key
+					return $r["result"];
+				break;
+			}
+		}
+		
+		if ($timeout > 0) {
+			$r = $agi->wait_for_digit($timeout);
+			if (($r["result"] != 0) || (!$loop)) {
+				// return only if the reult is not 0 (timeout)
+				// or we're not doing a loop
+				return $r["result"];
+			}
+		}
+		
+		if ($loop && (++$i > $loop)) {
+			return $loopreturn;
+		}
+	} while ($loop);
+	
+	return 0;
+}
+
+/** If $file.(wav|WAV|gsm|GSM) exists
+ */
+function sound_file_exists($file) {
+	global $agi;
+	
+	foreach (array("gsm","GSM","wav","WAV") as $ext) {
+		if (file_exists($file.".".$ext)) {
+			$agi->verbose("Found ".$file.".".$ext, 2);
+			return true;
+		}
+	}
+	return false;
+}
+
+function string_to_digits($string) {
+	$out = "";
+	
+	for($i=0; $i<strlen($string); $i++) {
+		switch (strtoupper($string[$i])) {
+			case '1':
+				$out .= '1';
+			break;
+			case '2': case 'A': case 'B': case 'C':
+				$out .= '2';
+			break;
+			case '3': case 'D': case 'E': case 'F':
+				$out .= '3';
+			break;
+			case '4': case 'G': case 'H': case 'I':
+				$out .= '4';
+			break;
+			case '5': case 'J': case 'K': case 'L':
+				$out .= '5';
+			break;
+			case '6': case 'M': case 'N': case 'O':
+				$out .= '6';
+			break;
+			case '7': case 'P': case 'Q': case 'R': case 'S':
+				$out .= '7';
+			break;
+			case '8': case 'T': case 'U': case 'V':
+				$out .= '8';
+			break;
+			case '9': case 'W': case 'X': case 'Y': case 'Z':
+				$out .= '9';
+			break;
+		}
+		
+		if ($i+1 == NUM_DIGITS) break;
+	}
+	
+	return $out;
+}
+
+function say_alpha($string,$escape_digits) {
+	$string = strtolower($string);
+	$files = array();
+	
+	for($i=0; $i<strlen($string); $i++) {
+		if (('a' <= $string[$i]) && ($string[$i] <= 'z')) {
+		
+			if (($string[$i] == 'z') && SAY_ZED) {
+				$files[] = "letters/zed";
+			} else {
+				$files[] = "letters/".$string[$i];
+			}
+			
+		} else if (('1' <= $string[$i]) && ($string[$i] <= '0')) {
+			$files[] = "digits/".$string[$i];
+			
+		} else {
+			switch ($string[$i]) {
+				case "@": $files[] = "letters/at"; break;
+				case "-": $files[] = "letters/dash"; break;
+				case "$": $files[] = "letters/dollar"; break;
+				case ".": $files[] = "letters/dot"; break;
+				case "=": $files[] = "letters/equals"; break;
+				case "!": $files[] = "letters/exclaimation-point"; break;
+				case "+": $files[] = "letters/plus"; break;
+				case "/": case "\\": $files[] = "letters/slash"; break;
+				case " ": $files[] = "letters/space"; break;
+			}
+		}
+	}
+	
+	return stream_multiple($files,$escape_digits);
+}
+
+function do_directory($type, &$directory, $dial_context, $say_exten, $operator) {
+	global $agi;
+	global $voicemail_dir;
+	
+	$escape_digits = "1*";
+	if ($operator) $escape_digits .= "0";
+	
+	switch ($type) {
+		case DIR_FIRST: $intro = ($operator ? "dir-intro-fn-oper" : "dir-intro-fn"); break;
+		case DIR_BOTH: $intro = ($operator ? "dir-intro-fnln-oper" : "dir-intro-fnln"); break;
+		case DIR_LAST: default: $intro = ($operator ? "dir-intro-oper" : "dir-intro"); break;
+	}
+	
+	$loop = 0;
+	while ($loop < MAX_REPEAT) {
+		$r = $agi->get_data($intro, 4000, NUM_DIGITS);
+		
+		if (($r["result"] == "0") && $operator) {
+			// operator
+			$agi->verbose("Dropping to operator");
+			// switch to o,1 in the current context
+			$agi->set_extension("o");
+			$agi->set_priority("1");
+			// exiting application immediately!
+			exit(0);
+		}
+		$digits = $r["result"];
+		
+		usleep(500); // pause a bit, so digit presses get cleared
+		
+		if ($digits !== "") {
+			// they entered SOMETHING, reset our loop
+			$loop = 0;
+		}
+		
+		$i = 0;
+		$digit = false;
+		if (isset($directory[$digits]) && isset($directory[$digits][$i])) {
+			$loop = 0; // reset loop counter
+			do {
+				$match = & $directory[$digits][$i];
+				
+				$maindirname = sprintf($voicemail_dir, $match["context"], $match["ext"]);
+
+				if (sound_file_exists($maindirname."/greet")) {
+					$r = $agi->stream_file($maindirname."/greet",$escape_digits);
+					if ($r["result"] > 0) $digit = $r["result"];
+				} else {
+					$digit = say_alpha($match["name"],$escape_digits);
+				}
+				
+				if (!$digit) {
+					$digit = stream_multiple("dir-instr", $escape_digits, 3000);
+				}
+				
+				switch ($digit) {
+					case D_1: // dial this
+						if ($say_exten) {
+							$agi->stream_file("pls-hold-while-try");
+							$agi->stream_file("to-extension");
+
+							$agi->say_digits($match["ext"]);
+						}
+						$agi->conlog("Dial ".$match["ext"]);
+						
+						$agi->set_context($dial_context);
+						$agi->set_extension($match["ext"]);
+						$agi->set_priority("1");
+						exit(0);
+					break;
+					case D_STAR: // not correct
+						$i += 1;
+					break;
+					case D_0: // operator
+						if ($operator) {
+							$agi->verbose("Dropping to operator");
+							// switch to o,1 in the current context
+							$agi->set_extension("o");
+							$agi->set_priority("1");
+							// exiting application immediately!
+							exit(0);
+						}
+					break;
+					case -1: // hungup
+						$agi->conlog("User hungup");
+						exit(1);
+					break;
+					case 0: // no response
+						$loop++;
+					break;
+					case -2: // loop timed out
+						$agi->stream_file("goodbye");
+						$agi->hangup();
+						exit(0);
+					break;
+				}
+				
+				if ($digit !== 0) {
+					$loop = 0;
+				}
+				$digit = false;
+			} while (isset($directory[$digits][$i]) && ($loop < MAX_REPEAT));
+			
+			if (!isset($directory[$digits][$i])) {
+				$agi->stream_file("dir-nomore");
+				$loop = 0; // reset our loop counter so it doesn't hangup
+			}
+		} else if (!empty($digits) || ($digits === "0")) {
+			// strict type checking as they may have entered "0" (string) which is empty()
+			$agi->stream_file("dir-nomatch");
+		} // else, we timed out
+		
+		$loop++;
+	}
+}
+
+/******************************************************************************/
+
+$agi = new AGI;
+
+$directory_file = get_var($agi, "ASTETCDIR")."/voicemail.conf";
+
+// where is voicemail stored?
+$voicemail_dir  = get_var($agi, "ASTSPOOLDIR")."/voicemail/%s/%d";
+
+// where should we store logs? (fixes #1912)
+$log_dir        = get_var($agi, "ASTLOGDIR");
+
+if (DEBUG) $logfile = fopen( $log_dir . "/directory.log","w");
+
+$vmconf = array();
+$null = null;
+parse_voicemailconf($directory_file, $vmconf, $null);
+
+
+if (!$argv[1]) {
+	$agi->verbose("Notice: vm-context not specified.  Using 'default'");
+	$vm_context = "default";
+} else {
+	$vm_context = trim($argv[1]);
+}
+
+if (!isset($vmconf[$vm_context]) && ($vm_context != "general")) {
+	// we make an exception for "general" context,as it just includes other contexts
+	$agi->verbose("Cannot find context ".$vm_context." in ".$directory_file);
+	exit(1);
+}
+
+if (isset($argv[2])) {
+	$dial_context = trim($argv[2]);
+} else {
+	$dial_context = $vm_context;
+}
+
+$operator = false;
+$dir_type = DIR_FIRST;
+$say_exten = false;
+
+if (isset($argv[3])) {
+	for($i=0; $i<strlen($argv[3]); $i++) {
+		switch ($argv[3][$i]) {
+			case "f": case "F": 
+				$dir_type = DIR_FIRST;
+			break;
+			case "l": case "L": 
+				$dir_type = DIR_LAST;
+			break;
+			case "b": case "B": 
+				$dir_type = DIR_BOTH;
+			break;
+			case "o": case "O": 
+				$operator = true;
+			break;
+			case "e": case "E": 
+				$say_exten = true;
+			break;
+		}
+	}
+}
+
+if ($vm_context == "general") {
+	$boxes = array();
+	foreach ($vmconf as $context=>$arr) {
+		// skip if it's general context -- this doesn't contain mailboxes
+		if ($context == "general") continue;
+		
+		foreach ($arr as $key=>$box) {
+			// we could do if !isset($boxes[$key]) to NOT override mailboxes
+			
+			// add in the context, otherwise we don't know what it is
+			$box["context"] = $context;
+			
+			$boxes[$key] = $box;
+		}
+	}
+} else {
+	$boxes = &$vmconf[$vm_context];
+}
+
+$directory = array();
+foreach ($boxes as $box) {
+	if (!empty($box["name"])) {
+		$name = explode(" ",$box["name"]);
+		
+		if (isset($box["context"])) {
+			$context = $box["context"];
+		} else {
+			$context = $vm_context;
+		}
+		
+		switch ($dir_type) {
+			case DIR_FIRST: // first name only
+				$digits = string_to_digits($name[0]);
+				$directory[$digits][] = array("ext"=>$box["mailbox"], "name"=>$box["name"], "context"=>$context);
+			break;
+			case DIR_BOTH: // all names
+				foreach ($name as $temp) {
+					$digits = string_to_digits($temp);
+					$directory[$digits][] = array("ext"=>$box["mailbox"], "name"=>$box["name"], "context"=>$context);
+				}
+			break;
+			case DIR_LAST: default: // last name only
+				$digits = string_to_digits(end($name));
+				$directory[$digits][] = array("ext"=>$box["mailbox"], "name"=>$box["name"], "context"=>$context);
+			break;
+		}
+	}
+}
+
+if (DEBUG) {
+	output($argv);
+	output($dir_type);
+	output($directory);
+}
+
+do_directory($dir_type, $directory, $dial_context, $say_exten, $operator);
+	
+?>

Propchange: freepbx-modules/trunk/modules/core/agi-bin/directory
------------------------------------------------------------------------------
    svn:executable = *

Added: freepbx-modules/trunk/modules/core/agi-bin/enumlookup.agi
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/agi-bin/enumlookup.agi?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/agi-bin/enumlookup.agi (added)
+++ freepbx-modules/trunk/modules/core/agi-bin/enumlookup.agi Mon Apr  7 13:18:05 2008
@@ -1,0 +1,137 @@
+#!/usr/bin/php -q
+<?php
+
+// Replacement for Asterisk's ENUMLOOKUP function. 
+// Written by Rob Thomas <xrobau at gmail.com>
+// Released under Version 2 of the GPL
+// Originally written for use with FreePBX.
+
+// Based on e164.org's enum.php script, available on http://www.e164.org/enum.phps
+
+/* --------WARNING---------
+ * 
+ * This script is auto-copied from an included module and will get overwritten.
+ * If you modify it, you must change it to write only, in the agi-bin directory,
+ * to keep it from getting changed.
+ */
+
+require_once "phpagi.php";
+
+$AGI = new AGI();
+$lookup = get_var( $AGI, "DIAL_NUMBER" );
+
+$enums = Array('e164.org', 'e164.arpa', 'e164.info');
+
+// Go through the ENUM providers and look for the number.
+
+$dialstr = "";
+
+foreach ($enums as $enum) {
+	// Are we using php5 and can use get_dns_record?
+		if (function_exists("dns_get_record")) {
+			$arr = get_php5($lookup, $enum);
+	// else, do we have Pear Net DNS?
+	// Disabled, as I couldn't easily get it working on my machine
+	//} elseif ((@include 'Net/DNS.php') =='OK') {
+	//	$arr = get_pear($arpa);
+	} else {
+		@exec('dig -h > /dev/null 2>&1 ', $res, $var);
+		if ($var != 127) { 
+			$arr = get_dig($lookup, $enum);
+		} else {
+			$AGI->verbose("ENUM LOOKUPS DISABLED due to php5 not being installed AND no dig command", "0");
+		}
+	}
+	if (isset($arr[0])) {
+		foreach($arr as $key => $row) {
+			$order[$key] = $row["order"];
+			$prio[$key] = $row["prio"];
+		}
+		array_multisort($order, SORT_ASC, $prio, SORT_ASC, $arr);
+		foreach ($arr as $key => $row) {
+			if (eregi('SIP|IAX', $row['tech']))
+				$dialstr .= $row['URI']."|";
+		}
+	}
+}
+
+$AGI->verbose("Setting DIALARR to $dialstr", 3);
+$AGI->set_variable("DIALARR", $dialstr);
+
+function get_dig($lookup, $enum) {
+	global $AGI;
+
+	$AGI->verbose("Looking up $lookup on $enum via shell command DIG",3);;
+	$arpa = "";
+	for ($i = 0; $i < strlen($lookup); $i++) {
+		$arpa = $lookup[$i].".".$arpa;
+	}
+	$lines = trim(`/usr/bin/dig +short ${arpa}${enum} naptr`);
+	$lines = explode("\n", $lines);
+	foreach($lines as $line) {
+		$line = trim($line);
+		if (preg_match("/^;;/", $line))
+			continue;
+		if (!isset($arr)) $arr = array();
+		$line = str_replace("\t", " ", $line);
+		while(strstr($line, "  "))
+			$line = str_replace("  ", " ", $line);
+		$line = str_replace("\"", "", $line);
+		$line = str_replace("\'", "", $line);
+		$line = str_replace(" ", "|", $line);
+		$bits = explode("|", $line);
+		$bit = explode("!", stripslashes($bits[4]));
+		$URI = ereg_replace($bit[1], $bit[2], "+".$lookup);
+		if($URI[3] == ":")
+			$URI[3] = "/";
+		if($URI[4] == ":")
+		$URI[4] = "/";
+		$arr[] = array("order" => $bits[0], "prio" => $bits[1], "tech" => $bits[3], "URI" => $URI);
+	}
+	if (isset($arr[0])) {
+		return $arr;
+	} else {
+		return null;
+	}
+}
+
+function get_php5($lookup, $enum) {
+	global $AGI;
+
+	$AGI->verbose("Looking up $lookup on $enum via dns_get_record",3);
+
+	$arpa = "";
+	for ($i = 0; $i < strlen($lookup); $i++) {
+		$arpa = $lookup[$i].".".$arpa;
+	}
+	$res = dns_get_record("$arpa$enum", DNS_NAPTR);
+	foreach ($res as $entry) {
+		if (!isset($arr)) $arr = array();
+		$bit = explode("!", $entry['regex']);
+		$URI = ereg_replace($bit[1], $bit[2], "+".$lookup);
+		if($URI[3] == ":") $URI[3] = "/";
+		if($URI[4] == ":") $URI[4] = "/";
+		$arr[] = array("order" => $entry['order'], "prio" => $entry['pref'], "tech" => $entry['services'], "URI" => $URI);
+	}
+	if (isset($arr[0])) {
+		return $arr;
+	} else {
+		return null;
+	}
+}
+
+
+// helper functions
+function get_var( $agi, $value)
+{
+	$r = $agi->get_variable( $value );
+
+	if ($r['result'] == 1)
+	{
+		$result = $r['data'];
+		return $result;
+	}
+	else return '';
+}
+
+?>

Propchange: freepbx-modules/trunk/modules/core/agi-bin/enumlookup.agi
------------------------------------------------------------------------------
    svn:executable = *

Added: freepbx-modules/trunk/modules/core/agi-bin/fixlocalprefix
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/agi-bin/fixlocalprefix?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/agi-bin/fixlocalprefix (added)
+++ freepbx-modules/trunk/modules/core/agi-bin/fixlocalprefix Mon Apr  7 13:18:05 2008
@@ -1,0 +1,251 @@
+#!/usr/bin/php -q
+<?php
+/**
+// fixlocalprefix Copyright (C) 2005 Greg MacLellan (greg at mtechsolutions.ca)
+// Asterisk Management Portal Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+/* --------WARNING---------
+ * 
+ * This script is auto-copied from an included module and will get overwritten.
+ * If you modify it, you must change it to write only, in the agi-bin directory,
+ * to keep it from getting changed.
+
+
+This program takes a number, checks it against a list of patterns for a specific trunk, and modifies the number based
+on the rules for that number.
+
+Two variables are required:
+
+DIAL_NUMBER - the number to be dialed (this will be modified, if necessary)
+DIAL_TRUNK - the trunk number to use
+
+The list of prefixes is contained in $localprefix_file (defined below, defaults to /etc/asterisk/localprefixes.conf). This
+file has the format:
+
+	[trunk-1]
+	rule1=1613|NXXXXXX
+	rule2=1519|555XXXX
+	rule2=1519|54[0-9]XXXX
+	
+	[trunk-2]
+	rule1=1613+NXXXXXX
+	rule2=1519+12XXXXX
+
+
+The section read depends on the value of DIAL_TRUNK. 
+
+A | means to drop the number before the |. In this example, if DIAL_NUMBER is "16135551234" and DIAL_TRUNK is "1", 
+DIAL_NUMBER will become "5551234" (rule1). If DIAL_NUMBER is "15195551234", it will become "5551234" (rule2). 
+"15195435555" will become "5435555" (rule3).
+
+A + means to prefix the beginning digits to the following pattern. In this example, if DIAL_NUMBER is 5551234, and 
+DIAL_TRUNK is "2", DIAL_NUMBER will become "16135551234". If DIAL_NUMBER is "1235555", it will match rule2 and
+become "15191235555". 
+
+If no number is matched, DIAL_NUMBER is left untouched, and the script will exit with return value 0. If any errors 
+occur, DIAL_NUMBER is left untouched and the script will exit with return value 1.
+
+There is no limit to the number of rules that may be defined.
+
+You can also use #include filename.conf to include other files. Sections are preserved when including, which may
+cause undesired behaviour if not planned for. For example:
+
+localprefixes.conf:
+	[trunk-1]
+	#include t1.conf
+	rule1=1613|453XXXX
+	rule2=1613|384XXXX
+	
+t1.conf:
+	[trunk-2]
+	rule1=141|NXXXXXX
+	
+rule1 and rule2 defined in localprefixes.conf will actually belong to [trunk-2], and additionally, rule1 in 
+localprefixes.conf will override the rule1 defined in t1.conf.
+
+*/
+
+include("phpagi.php");
+
+function get_var( $agi, $value)
+{
+	$r = $agi->get_variable( $value );
+	
+	if ($r['result'] == 1)
+	{
+		$result = $r['data'];
+		return $result;
+	}
+	else
+		return '';
+}
+
+function parse_conf($filename, &$conf, &$section) {
+	if (is_null($conf)) {
+		$conf = array();
+	}
+	if (is_null($section)) {
+		$section = "general";
+	}
+	
+	if (file_exists($filename)) {
+		$fd = fopen($filename, "r");
+		while ($line = fgets($fd, 1024)) {
+			if (preg_match("/^\s*([a-zA-Z0-9-_]+)\s*=\s*(.*?)\s*([;#].*)?$/",$line,$matches)) {
+				// name = value
+				// option line
+				$conf[$section][ $matches[1] ] = $matches[2];
+			} else if (preg_match("/^\s*\[(.+)\]/",$line,$matches)) {
+				// section name
+				$section = strtolower($matches[1]);
+			} else if (preg_match("/^\s*#include\s+(.*)\s*([;#].*)?/",$line,$matches)) {
+				// include another file
+				
+				if ($matches[1][0] == "/") {
+					// absolute path
+					$filename = $matches[1];
+				} else {
+					// relative path
+					$filename =  dirname($filename)."/".$matches[1];
+				}
+				
+				parse_conf($filename, $conf, $section);
+			}
+		}
+	}
+}
+
+function sanitizeNumber($number) {
+	global $agi;
+	if (strpos($number,"-") !== false) {
+		$agi->verbose("Stripping hyphens");
+		$number = str_replace("-","",$number);
+	}
+	return $number;	
+}
+
+function fixNumber($pattern, $number, &$agi) {
+	// valid chars in a pattern are 0-9XNZwW#*\.\[\]\-\+\|
+	$chars = '0-9XNZwW#*\.\[\]\-'; //escaped pcre-ready
+	
+	// convert x n and z to uppercase
+	$regex = str_replace(array('x','n','z'), array('X','N','Z'), $pattern);
+	// sanitize the pattern - remove any non-pattern chars
+	$regex = preg_replace("/[^0-9XNZwW#*\.\[\]\-\+\|]/", "", $regex);
+	// Also kill the '-' characters outside of groups
+	$regex = preg_replace("/((?:\[[^\]]*\])*)([^\[\]\-]*)-?/", "$1$2", $regex);
+
+	$agi->verbose('Using pattern '.$regex, 4);
+	// attempt to grab the pieces of the pattern
+	if (preg_match('/^(([0-9XNZwW#*\.\[\]\-]+)\|)?(([0-9XNZwW#*\.\[\]\-]+)\+)?([0-9XNZwW#*\.\[\]\-]+)$/', $regex, $matches)) {
+		// one of NXXXXXX, 613|NXXXXXX   1+NXXXXXX    613|1+NXXXXXX,  
+		// matches[2] = drop (eg 613),  matches[4] = prefix (eg 1),  matches[5] = rest of number (eg NXXXXX)
+		
+		$drop = $matches[2];
+		$prefix = $matches[4];
+		$static = $matches[5];
+	} else if (preg_match('/^(([0-9XNZwW#*\.\[\]\-]+)\+)?(([0-9XNZwW#*\.\[\]\-]+)\|)?([0-9XNZwW#*\.\[\]\-]+)$/', $regex, $matches)) {
+		// one of NXXXXXX,  613|NXXXXXX   1+NXXXXXX    1+613|NXXXXXX
+		// matches[2] = prefix (eg 1),  matches[4] = drop (eg 613),  matches[5] = rest of number (eg NXXXXX)
+		
+		$drop = $matches[4];
+		$prefix = $matches[2];
+		$static = $matches[5];
+	} else {
+		if (!is_null($agi)) {
+			$agi->verbose('Could not understand pattern "'.$pattern.'" ('.$regex.')', 1);
+		}
+		return false;
+	}
+	
+	// convert asterisk pattern matching into perl regular expression
+	$regex = str_replace(
+			array(
+				"X",
+				"Z",
+				"N",
+				".",
+			),
+			array(
+				"[0-9]",
+				"[1-9]",
+				"[2-9]",
+				"[0-9#*]+",
+			),
+			// note, we're doing a subpattern match on the static portion so it can be extracted later
+			$drop.'('.$static.')');
+	
+	if (preg_match('/^'.$regex.'$/', $number, $matches)) {
+		return $prefix.$matches[1];
+	}
+	return false;
+}
+
+/**********************************************************************************************************************/
+
+$agi = new AGI();
+
+$localprefix_file = get_var($agi, "ASTETCDIR")."/localprefixes.conf";
+
+if (file_exists($localprefix_file)) {
+	parse_conf($localprefix_file, $conf, $section);
+	if (count($conf) == 0) {
+//		$agi->verbose("Could not parse ".$localprefix_file);
+		exit(1);
+	}
+} else {
+	$agi->verbose("Could not open ".$localprefix_file);
+	exit(1);
+}
+
+$r = $agi->get_variable("DIAL_NUMBER");
+if ($r["result"] == 0) {
+	$agi->verbose("DIAL_NUMBER not set -- nothing to do");
+	exit(1);
+}
+$number = $r["data"];
+
+$number = sanitizeNumber($number);
+
+$r = $agi->get_variable("DIAL_TRUNK");
+if ($r["result"] == 0) {
+	$agi->verbose("DIAL_TRUNK not set -- nothing to do");
+	exit(1);
+}
+$trunk = $r["data"];
+
+
+if (isset($conf["trunk-$trunk"])) {
+	foreach ($conf["trunk-$trunk"] as $key=>$rule) {
+		// extract all ruleXX keys
+		//$agi->conlog("$key = $rule");
+		if (preg_match("/^rule\d+$/",$key)) {
+			// $rule is a dial rule
+			
+			if ($newnum = fixNumber($rule, $number, $agi)) {
+				$agi->verbose('Dialpattern '.$rule.' matched. '.$number.' -> '.$newnum, 2);
+				$agi->set_variable("DIAL_NUMBER", $newnum);
+				
+				// reverted back form r2080 (r2081 on trac) so that any pattern match will end
+				// the loop. This needs to stay like this for backwards compatibility and often
+				// patterns are used to avoid matching substitution rules for exception cases.
+				exit(0);
+			} // else, it didn't match this rule
+		} // else, this isn't a rule
+	} 
+} // else, no config for this section
+
+// we just exit with no changes to the variable.
+exit(0);
+
+?>

Propchange: freepbx-modules/trunk/modules/core/agi-bin/fixlocalprefix
------------------------------------------------------------------------------
    svn:executable = *

Added: freepbx-modules/trunk/modules/core/agi-bin/list-item-remove.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/agi-bin/list-item-remove.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/agi-bin/list-item-remove.php (added)
+++ freepbx-modules/trunk/modules/core/agi-bin/list-item-remove.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,58 @@
+#!/usr/bin/php -q
+<?php
+
+/*
+Removes an item from a character delimited list.
+
+Usage: list-item-remove.php list item varname [listseparator]
+
+list: The list of strings separated by a character (example: 1&2&3)
+item: The value of the item to remove
+varname: The variable to return the new list in
+listseparator: The separator.  This defaults to "&" if it is not specified.
+*/
+
+/* --------WARNING---------
+ * 
+ * This script is auto-copied from an included module and will get overwritten.
+ * If you modify it, you must change it to write only, in the agi-bin directory,
+ * to keep it from getting changed.
+ */
+
+include("phpagi.php");
+
+$agi = new AGI;
+
+if (!isset($argv[1])) {
+        $agi->verbose("Missing list");
+        exit(1);
+}
+
+if (!isset($argv[2])) {
+        $agi->verbose("Missing item");
+        exit(1);
+}
+
+if (!isset($argv[3])) {
+        $agi->verbose("Missing return var name");
+        exit(1);
+}
+
+$arglist = $argv[1];
+$argitem = $argv[2];
+$argvarname = $argv[3];
+
+if (isset($argv[4])) {
+        $argsep = "&";
+} else {
+        $argsep = $argv[4];
+}
+
+$newlist = str_replace($argitem.$argsep, "", $arglist.$argsep);
+
+if (substr($newlist, -1, 1) == $argsep) {
+        $newlist = substr($newlist, 0, -1);
+}
+
+$agi->set_variable($argvarname, $newlist);
+?>

Propchange: freepbx-modules/trunk/modules/core/agi-bin/list-item-remove.php
------------------------------------------------------------------------------
    svn:executable = *

Added: freepbx-modules/trunk/modules/core/agi-bin/recordingcheck
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/agi-bin/recordingcheck?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/agi-bin/recordingcheck (added)
+++ freepbx-modules/trunk/modules/core/agi-bin/recordingcheck Mon Apr  7 13:18:05 2008
@@ -1,0 +1,132 @@
+#!/usr/bin/php -q
+<?php
+/**
+// recordingcheck Copyright (C) Coalescent Systems Inc. (info at coalescentsystems.ca)
+// Asterisk Management Portal Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+The program checks determines if Asterisk should record a call
+*/
+
+/* --------WARNING---------
+ * 
+ * This script is auto-copied from an included module and will get overwritten.
+ * If you modify it, you must change it to write only, in the agi-bin directory,
+ * to keep it from getting changed.
+ */
+
+
+include("phpagi.php");
+
+
+/**********************************************************************************************************************/
+
+$agi = new AGI();
+
+$timestamp = $argv[1];
+$uniqueid = $argv[2];
+$type = $agi->get_variable("ARG2");
+
+switch($type['data']) {
+	case "Group":
+	
+		$r = $agi->get_variable("ARG1");
+		if ($r["result"] == 0) {
+			$agi->verbose("Extension List not set -- nothing to do");
+			exit(1);
+		}
+		$extenlist = $r["data"];
+		
+		$agi->set_variable("RecEnable", "DISABLED"); //disable by default
+		
+		$list = explode("-",$extenlist);
+		if(!empty($list)) {
+			foreach($list as $exten) {
+				$setting = $agi->database_get("AMPUSER",$exten."/recording");
+				if ($setting["result"] == 0) {
+					$agi->verbose("No DB Entry AMPUSER/$exten/recording - Not recording");
+					exit(1);
+				}
+				//explode recording vars
+				$recording = explode("|",$setting["data"]);
+				$recout = substr($recording[0],4);
+				$recin = substr($recording[1],3);
+				if ($recin == "Always") {
+					$agi->verbose("Recording enable for ".$exten);
+					$agi->verbose("CALLFILENAME=g{$exten}-{$timestamp}-{$uniqueid}");
+					$agi->set_variable("CALLFILENAME","g{$exten}-{$timestamp}-{$uniqueid}");
+					$agi->set_priority(999);
+					exit(0);
+				}
+			}
+		} else {
+			$agi->verbose("Extension List is empty -- nothing to do");
+			exit(1);		
+		}
+	
+	break;
+	case "OUT":
+		$exten = $agi->get_variable("ARG1");
+		
+		$options = $agi->database_get("AMPUSER","{$exten['data']}/recording");
+		
+		if ($options["result"] == "0") {
+			$agi->verbose("No AMPUSER db entry for ".$exten["data"].". Not recording");
+			exit(1);		
+		}
+
+		//explode recording vars
+		$recording = explode("|",$options["data"]);
+		$recout = substr($recording[0],4);
+		$recin = substr($recording[1],3);
+	
+		if($recout == "Always") {
+			$agi->verbose("Outbound recording enabled.");
+			$agi->verbose("CALLFILENAME=OUT{$exten['data']}-{$timestamp}-{$uniqueid}");
+			$agi->set_variable("CALLFILENAME","OUT{$exten['data']}-{$timestamp}-{$uniqueid}");
+			$agi->set_priority(999);
+			exit(0);
+		} else {
+			$agi->verbose("Outbound recording not enabled");
+			exit(1);		
+		}
+	break;
+	case "IN":
+		$exten = $agi->get_variable("ARG1");	
+		$options = $agi->database_get("AMPUSER","{$exten['data']}/recording");
+		
+		if ($options["result"] == "0") {
+			$agi->verbose("No AMPUSER db entry for ".$exten["data"].". Not recording");
+			exit(1);		
+		}
+		//explode recording vars
+		$recording = explode("|",$options["data"]);
+		$recout = substr($recording[0],4);
+		$recin = substr($recording[1],3);
+		
+		if($recin == "Always")  {
+			$agi->verbose("Inbound recording enabled.");
+			$agi->verbose("CALLFILENAME={$timestamp}-{$uniqueid}");
+			$agi->set_variable("CALLFILENAME","{$timestamp}-{$uniqueid}");
+			$agi->set_priority(999);
+			exit(0);	
+		} else {
+			$agi->verbose("Inbound recording not enabled");
+			exit(1);		
+		}
+	break;
+}
+
+// we just exit with no changes to the variable.
+exit(1);
+
+?>

Propchange: freepbx-modules/trunk/modules/core/agi-bin/recordingcheck
------------------------------------------------------------------------------
    svn:executable = *

Added: freepbx-modules/trunk/modules/core/bin/fax-process.pl
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/bin/fax-process.pl?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/bin/fax-process.pl (added)
+++ freepbx-modules/trunk/modules/core/bin/fax-process.pl Mon Apr  7 13:18:05 2008
@@ -1,0 +1,180 @@
+#!/usr/bin/perl -w
+
+# Small program to process a tiff file into a PDF and email it. 
+#
+# Distributed under the terms of the GNU General Public License (GPL) Version 2
+# Copyright 2005 by Rob Thomas (xrobau at gmail.com)
+
+use MIME::Base64;
+use Net::SMTP;
+
+# Default paramaters
+my $to = "xrobau\@gmail.com";
+my $from = "fax\@";
+my $subject = "Fax received";
+my $ct = "application/x-pdf";
+my $file = undef;
+my $attachment = undef;
+
+# Care about the hostname.
+my $hostname = `/bin/hostname`;
+chomp ($hostname);
+if ($hostname =~ /localhost/) {
+	$hostname = "set.your.hostname.com";
+}
+$from .= $hostname;
+
+# Usage:
+my $usage="Usage: --file filename [--attachment filename] [--to email_address] [--from email_address] [--type content/type] [--subject \"Subject Of Email\"]"; 
+
+# Parse command line..
+while (my $cmd = shift @ARGV) {
+  chomp $cmd;
+  # My kingdom for a 'switch'
+  if ($cmd eq "--to") {
+	my $tmp = shift @ARGV;
+	$to = $tmp if (defined $tmp);
+  } elsif ($cmd eq "--subject") {
+	my $tmp = shift @ARGV;
+	if ($tmp =~ /\^(\")|^(\')/) {
+		# It's a quoted string
+		my $delim = $+;   # $+ is 'last match', which is ' or "
+		$tmp =~ s/\Q$delim\E//; # Strip out ' or "
+		$subject = $tmp;
+		while ($tmp = shift @ARGV) {
+			if ($tmp =~ /\Q$delim\E/) {
+				$tmp =~ s/\Q$delim\E//;
+				last;
+			}
+		$subject .= $tmp;
+		}
+	} else {
+		# It's a single word
+		$subject = $tmp;
+	}
+  # Convert %2x to proper characters, leave anything else alone.
+  $subject =~ s/\%20/ /g;
+    $subject =~ s/\%21/\!/g;
+    $subject =~ s/\%22/\"/g;
+    $subject =~ s/\%23/\#/g;
+    $subject =~ s/\%24/\$/g;
+    $subject =~ s/\%25/\%/g;
+    $subject =~ s/\%26/\&/g;
+    $subject =~ s/\%27/\'/g;
+    $subject =~ s/\%28/\(/g;
+    $subject =~ s/\%29/\)/g;
+    $subject =~ s/\%2a/\*/g;
+    $subject =~ s/\%2A/\*/g;
+    $subject =~ s/\%2b/\+/g;
+    $subject =~ s/\%2B/\+/g;
+    $subject =~ s/\%2c/\,/g;
+    $subject =~ s/\%2C/\,/g;
+    $subject =~ s/\%2d/\-/g;
+    $subject =~ s/\%2D/\-/g;
+    $subject =~ s/\%2e/\./g;
+    $subject =~ s/\%2E/\./g;
+    $subject =~ s/\%2f/\//g;
+    $subject =~ s/\%2F/\//g;
+  } elsif ($cmd eq "--type") {
+	my $tmp = shift @ARGV;
+	$ct = $tmp if (defined $tmp);
+  } elsif ($cmd eq "--from") {
+	my $tmp = shift @ARGV;
+	$from = $tmp if (defined $tmp);
+  } elsif ($cmd eq "--file") {
+	my $tmp = shift @ARGV;
+	$file = $tmp if (defined $tmp);
+  } elsif ($cmd eq "--attachment") {
+	my $tmp = shift @ARGV;
+	$attachment = $tmp if (defined $tmp);
+  } else {
+	die "$cmd not understood\n$usage\n";
+  }
+
+}
+
+# OK. All our variables are set up.
+# Lets make sure that we know about a file...
+die $usage unless $file;
+# and that the file exists...
+open( FILE, $file ) or die "Error opening $file: $!"; 
+# Oh, did we possibly not specify an attachment name?
+$attachment = $file unless ($attachment);
+
+my $encoded="";
+my $buf="";
+# First, lets find out if it's a TIFF file
+read(FILE, $buf, 4);
+if ($buf eq "MM\x00\x2a" || $buf eq "II\x2a\x00") {
+	# Tiff magic - We need to convert it to pdf first
+	# Need to do some error testing here - what happens if tiff2pdf
+	# doesn't exist?
+	open PDF, "tiff2pdf $file|";
+	$buf = "";
+	while (read(PDF, $buf, 60*57))  {
+  		$encoded .= encode_base64($buf);
+	}
+	close PDF;
+} else {
+	# It's a PDF already
+	# Go back to the start of the file, and start again
+	seek(FILE, 0, 0); 
+	while (read(FILE, $buf, 60*57)) {
+		$encoded .= encode_base64($buf);
+	}
+}
+close FILE;
+
+# Now we have the file, we should ensure that there's no paths on the
+# filename..
+$attachment =~ s/^.+\///;
+
+# And that's pretty much all the hard work done. Now we just create the
+# headers for the MIME encapsulation: 
+my $boundary = '------FREEPBX_FAX_MAIL:'; 
+my $dtime = `date`;
+chomp $dtime;
+my @chrs = ('0' .. '9', 'A' .. 'Z', 'a' .. 'z'); 
+foreach (0..16) { $boundary .= $chrs[rand (scalar @chrs)]; } 
+
+my $len = length $encoded;
+# message body..
+my $msg ="Content-Class: urn:content-classes:message
+Content-Transfer-Encoding: 7bit
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary=\"$boundary\"
+From: $from
+Date: $dtime
+Reply-To: $from
+X-Mailer: dofaxmail.pl
+To: $to
+Subject: $subject
+
+This is a multi-part message in MIME format.
+
+--$boundary 
+Content-Type: text/plain; charset=\"us-ascii\"
+Content-Transfer-Encoding: quoted-printable
+
+A Fax has been recieved by the fax gateway, and is attached to this message.
+
+
+--$boundary
+Content-Type: $ct; name=\"$attachment\"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename=\"$attachment\"
+
+$encoded 
+--$boundary-- 
+";
+
+#print "$msg";
+# Now we just send it.
+my $smtp = Net::SMTP-> new("127.0.0.1", Debug => 0) or
+  die "Net::SMTP::new: $!";
+$smtp-> mail($from);
+$smtp-> recipient($to);
+$smtp-> data();
+$smtp-> datasend($msg);
+$smtp-> dataend();
+

Propchange: freepbx-modules/trunk/modules/core/bin/fax-process.pl
------------------------------------------------------------------------------
    svn:executable = *

Added: freepbx-modules/trunk/modules/core/etc/extensions.conf
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/etc/extensions.conf?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/etc/extensions.conf (added)
+++ freepbx-modules/trunk/modules/core/etc/extensions.conf Mon Apr  7 13:18:05 2008
@@ -1,0 +1,1439 @@
+; FreePBX
+; Copyright (C) 2004 Coalescent Systems Inc (Canada)
+; Copyright (C) 2006 Why Pay More 4 Less Pty Ltd (Australia)
+; Released under the GNU GPL Licence version 2.
+
+; dialparties.agi (http://www.sprackett.com/asterisk/)
+; Asterisk::AGI (http://asterisk.gnuinter.net/)
+; gsm (http://www.ibiblio.org/pub/Linux/utils/compress/!INDEX.short.html)
+; loligo sounds (http://www.loligo.com/asterisk/sounds/)
+; mpg123 (http://voip-info.org/wiki-Asterisk+config+musiconhold.conf)
+
+;**************************  -WARNING-  ****************************************
+;                                                                              *
+; This include file is to be used with extreme caution. In almost all cases    *
+; any custom dialplan SHOULD be put in extensions_custom.conf which will       *
+; not hurt freepbx generated dialplan. In some very rare and custom situation  *
+; users have a need to override what freepbx generates. Anything in this file  *
+; will do such.                                                                *
+;                                                                              *
+#include extensions_override_freepbx.conf
+;                                                                              *
+;**************************  -WARNING-  ****************************************
+
+; include extension contexts generated from AMP
+#include extensions_additional.conf
+
+; Customizations to this dialplan should be made in extensions_custom.conf
+; See extensions_custom.conf.sample for an example
+#include extensions_custom.conf
+
+[from-trunk]							; just an alias since VoIP shouldn't be called PSTN
+include => from-pstn
+
+[from-pstn]
+include => from-pstn-custom                     ; create this context in extensions_custom.conf to include customizations
+include => ext-did
+include => ext-did-catchall		; THIS MUST COME AFTER ext-did
+include => from-did-direct		; MODIFICATOIN (PL) for findmefollow if enabled, should be bofore ext-local
+exten => fax,1,Goto(ext-fax,in_fax,1)
+
+; MODIFICATION (PL) 
+;
+; Required to assure that direct dids go to personal ring group before local extension.
+; This could be auto-generated however I it is prefered to be put here and hard coded
+; so that it can be modified if ext-local should take precedence in certain situations.
+; will have to decide what to do later.
+;
+[from-did-direct]
+include => ext-findmefollow
+include => ext-local
+
+
+
+; ############################################################################
+; Macros [macro]
+; ############################################################################
+
+; Rings one or more extensions.  Handles things like call forwarding and DND
+; We don't call dial directly for anything internal anymore.
+; ARGS: $TIMER, $OPTIONS, $EXT1, $EXT2, $EXT3, ...
+; Use a Macro call such as the following: 
+;  Macro(dial,$DIAL_TIMER,$DIAL_OPTIONS,$EXT1,$EXT2,$EXT3,...)
+[macro-dial]
+exten => s,1,GotoIf($["${MOHCLASS}" = ""]?dial)
+exten => s,2,SetMusicOnHold(${MOHCLASS})
+exten => s,3(dial),AGI(dialparties.agi)
+exten => s,4,NoOp(Returned from dialparties with no extensions to call and DIALSTATUS: ${DIALSTATUS})
+
+exten => s,10,Dial(${ds})                               ; dialparties will set the priority to 10 if $ds is not null
+exten => s,11,Set(DIALSTATUS=${IF($["${DIALSTATUS_CW}"!="" ]?${DIALSTATUS_CW}:${DIALSTATUS})})
+
+exten => s,20,NoOp(Returned from dialparties with hunt groups to dial )
+exten => s,21,Set(HuntLoop=0)
+exten => s,22,GotoIf($[${HuntMembers} >= 1]?30 )  ; if this is from rg-group, don't strip prefix
+exten => s,23,NoOp(Returning there are no members left in the hunt group to ring)
+
+exten => s,30,Set(HuntMember=HuntMember${HuntLoop})
+exten => s,31,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["${RingGroupMethod}" = "hunt" ]]?32:35 )  ; Set CAll Trace for Hunt member we are going to call
+exten => s,32,Set(CT_EXTEN=${CUT(ARG3,,$[${HuntLoop} + 1])})
+exten => s,33,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT})
+exten => s,34,Goto(s,42)
+
+exten => s,35,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["${RingGroupMethod}" = "memoryhunt" ]]?36:50 )  ;Set Call Trace for each hunt member we are going to call "Memory groups have multiple members to set CALL TRACE For hence the loop
+exten => s,36,Set(CTLoop=0)
+exten => s,37,GotoIf($[${CTLoop} > ${HuntLoop}]?42 )  ; if this is from rg-group, don't strip prefix
+exten => s,38,Set(CT_EXTEN=${CUT(ARG3,,$[${CTLoop} + 1])})
+exten => s,39,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT})
+exten => s,40,Set(CTLoop=$[1 + ${CTLoop}])
+exten => s,41,Goto(s,37)
+        
+exten => s,42,Dial(${${HuntMember}}${ds} ) ; dialparties will set the priority to 20 if $ds is not null and its a hunt group
+exten => s,43,Set(HuntLoop=$[1 + ${HuntLoop}])
+exten => s,44,GotoIf($[$[$["foo${RingGroupMethod}" != "foofirstavailable"] & $["foo${RingGroupMethod}" != "foofirstnotonphone"]] | $["foo${DialStatus}" = "fooBUSY"]]?46)
+exten => s,45,Set(HuntMembers=0)
+exten => s,46,Set(HuntMembers=$[${HuntMembers} - 1])
+exten => s,47,Goto(s,22)
+exten => s,50,DBdel(CALLTRACE/${CT_EXTEN})
+exten => s,51,Goto(s,42)
+
+; make sure hungup calls go here so that proper cleanup occurs from call confirmed calls and the like
+;
+exten => h,1,Macro(hangupcall)
+
+; Ring an extension, if the extension is busy or there is no answer send it
+; to voicemail
+; ARGS: $VMBOX, $EXT
+[macro-exten-vm]
+exten => s,1,Macro(user-callerid)
+
+exten => s,n,Set(FROMCONTEXT=exten-vm)
+exten => s,n,Set(VMBOX=${ARG1})
+exten => s,n,Set(EXTTOCALL=${ARG2})
+exten => s,n,Set(CFUEXT=${DB(CFU/${EXTTOCALL})})
+exten => s,n,Set(CFBEXT=${DB(CFB/${EXTTOCALL})})
+exten => s,n,Set(RT=${IF($[$["${VMBOX}"!="novm"] | $["foo${CFUEXT}"!="foo"]]?${RINGTIMER}:"")})
+exten => s,n,Macro(record-enable,${EXTTOCALL},IN)
+
+exten => s,n,Macro(dial,${RT},${DIAL_OPTIONS},${EXTTOCALL})
+exten => s,n,Set(SV_DIALSTATUS=${DIALSTATUS})
+exten => s,n,GosubIf($[$["${SV_DIALSTATUS}"="NOANSWER"] & $["foo${CFUEXT}"!="foo"]]?docfu,1) ; check for CFU in use on no answer
+exten => s,n,GosubIf($[$["${SV_DIALSTATUS}"="BUSY"] & $["foo${CFBEXT}"!="foo"]]?docfb,1) ; check for CFB in use on busy
+exten => s,n,Set(DIALSTATUS=${SV_DIALSTATUS})
+exten => s,n,NoOp(Voicemail is '${VMBOX}')
+exten => s,n,GotoIf($["${VMBOX}" = "novm"]?s-${DIALSTATUS},1) ; no voicemail in use for this extension
+exten => s,n,NoOp(Sending to Voicemail box ${EXTTOCALL})
+exten => s,n,Macro(vm,${VMBOX},${DIALSTATUS})
+
+; Try the Call Forward on No Answer / Unavailable number
+exten => docfu,1,Set(RTCFU=${IF($["${VMBOX}"!="novm"]?${RINGTIMER}:"")})
+exten => docfu,n,Dial(Local/${CFUEXT}@from-internal/n,${RTCFU},${DIAL_OPTIONS})
+exten => docfu,n,Return
+
+; Try the Call Forward on Busy number
+exten => docfb,1,Set(RTCFB=${IF($["${VMBOX}"!="novm"]?${RINGTIMER}:"")})
+exten => docfb,n,Dial(Local/${CFBEXT}@from-internal/n,${RTCFB},${DIAL_OPTIONS})
+exten => docfb,n,Return
+
+; Extensions with no Voicemail box reporting BUSY come here
+exten => s-BUSY,1,NoOp(Extension is reporting BUSY and not passing to Voicemail)
+exten => s-BUSY,n,Playtones(busy)
+exten => s-BUSY,n,Busy(20)
+
+; Anything but BUSY comes here
+exten => _s-.,1,Playtones(congestion)
+exten => _s-.,n,Congestion(10)
+
+;------------------------------------------------------------------------
+; [macro-vm]
+;------------------------------------------------------------------------
+; CONTEXT:      macro-vm
+; PURPOSE:      call voicemail system and extend with personal ivr
+;
+; Under normal use, this macro will call the voicemail system with the extension and
+; desired greeting mode of busy, unavailable or as specified with direct voicemail
+; calls (usually unavailable) when entered from destinations.
+;
+; The voicemail system's two greetings have been 'hijacked' as follows to extend the
+; system by giving the option of a private 'ivr' for each voicemail user. The following
+; applies to both the busy and unavailable modes of voicemail and can be applied to one
+; or both, and differently.
+;
+; Global Defaults:
+;
+; The following are default values, used in both busy and unavail modes if no specific
+; values are specified.
+;
+; VMX_REPEAT
+;					The number of times to repeat the users message if no option is pressed.
+; VMX_TIMEOUT
+;					The timeout to wait after playing message before repeating or giving up.
+; VMX_LOOPS
+;					The number of times it should replay the message and check for an option when
+;					an invalid option is pressed.
+;
+; VMX_OPTS_DOVM
+;					Default voicemail option to use if vm is chosen as an option. No options will
+;					cause Allison's generic message, 's' will go straight to beep.
+; VMX_OPTS_TIMEOUT
+;					Default voicemail option to use if it times out with no options. No options will
+;					cause Allison's generic message, 's' will go straight to beep.
+;					IF THE USER PRESSES # - it will look like a timeout as well since no option will
+;					be presented. If the user wishes to enable a mode where a caller can press #
+;					during their message and it goes straight to voicemail with only a 'beep' then
+;					this should be set to 's'.
+; VMX_OPTS_LOOPS
+;					Default voicemail option to use if to many wrong options occur. No options will
+;					cause Allison's generic message, 's' will go straight to beep.
+;
+; VMX_CONTEXT
+;					Default context for user destinations if not supplied in the user's settings
+; VMX_PRI
+;					Default priority for user destinations if not supplied in the user's settings
+;
+; VMX_TIMEDEST_CONTEXT
+;					Default context for timeout destination if not supplied in the user's settings
+; VMX_TIMEDEST_EXT
+;					Default extension for timeout destination if not supplied in the user's settings
+; VMX_TIMEDEST_PRI
+;					Default priority for timeout destination if not supplied in the user's settings
+;
+; VMX_LOOPDEST_CONTEXT
+;					Default context for loops  destination if not supplied in the user's settings
+; VMX_LOOPDEST_EXT
+;					Default extension for loops  destination if not supplied in the user's settings
+; VMX_LOOPDEST_PRI
+;					Default priority for loops  destination if not supplied in the user's settings
+;
+;
+; The AMPUSER database variable has been extended with a 'vmx' tree (vm-extension). A
+; duplicate set is included for both unavail and busy. You could choose for to have an
+; ivr when unavail is taken, but not with busy - or a different once with busy.
+; The full list is below, each specific entry is futher described:
+;
+; state:		Whether teh current mode is enabled or disabled. Anything but 'enabled' is
+;						treated as disabled.
+; repeat:		This is the number of times that the users message should be played after the
+;						timeout if the user has not entered anything. It is just a variable to the
+;						Read() function which will do the repeating.
+; timeout:	This is how long to wait after the message has been read for a response from
+;						the user. A caller can enter a digit any time during the playback.
+; loops:		This is the number of loops that the system will allow a caller to retry if
+;						they enter a bad menu choice, before going to the loop failover destination
+; vmxopts:	This is the vm options to send to the voicemail command used when a specific
+;						voicemail destination is chosen (inidcated by 'dovm' in the ext field). This is
+;						typically either set to 's' or left blank. When set to 's' there will be no
+;						message played when entering the voicemail, just a beep. When blank, you will
+;						have Allison's generic message played. It is not typical to play the greetings
+;						since they have been 'hijacked' for these IVR's and from a caller's perspecitive
+;						this system appears interconnected with the voicemail so instructions can be
+;						left there.
+; timedest: The three variables: ext, context and pri are the goto destination if the caller
+;						enters no options and it timesout. None have to be set and a system default
+;						will be used. If just ext is set, then defaults will be used for context and
+;						pri, etc.
+; loopdest:	This is identical to timedest but used if the caller exceeds the maximum invalid
+;						menu choices.
+; [0-9*]:		The user can specify up to 11 ivr options, all as single digits from 0-9 or *. The
+;						# key can not be used since it is used as a terminator key for the Read command
+;						and will never be returned. A minimum of the ext must be specified for each valid
+;						option and as above, the context and priority can also be specified if the default
+;						is not to be used.
+;						Option '0' takes on a special meaning. Since a user is able to break out of the
+;						voicemail command once entering it with a 0, if specified, the 0 destination will
+;						be used.
+;						Option '*' can also be used to breakout. It is undecided at this point whether
+;						providing that option will be used as well. (probably should).
+;
+;
+; /AMPUSER/<ext>/vmx/[busy|unavail]/state:								enabled|disabled
+; /AMPUSER/<ext>/vmx/[busy|unavail]/repeat:								n (times to repeat message)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/timeout:							n (timeout to wait for digit)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/loops:								n (loop returies for invalid entries)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/vmxopts/dovm:					vmoptions (if ext is dovm)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/vmxopts/timeout:			vmoptions (if timeout)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/vmxopts/loops:				vmoptions (if loops)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/timedest/ext:					extension (if timeout)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/timedest/context:			context (if timeout)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/timedest/pri:					priority (if timeout)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/loopdest/ext:					extension (if too many failures)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/loopdest/context:			context (if too many failures)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/loopdest/pri:					priority (if too many failures)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/[0-9*]/ext:						extension (dovm for vm access)
+; /AMPUSER/<ext>/vmx/[busy|unavail]/[0-9*]/context:				context 
+; /AMPUSER/<ext>/vmx/[busy|unavail]/[0-9*]/pri:						priority 
+;------------------------------------------------------------------------
+[macro-vm]
+; ARG1 - extension
+; ARG2 - DIRECTDIAL/BUSY
+exten => s,1,Macro(user-callerid,SKIPTTL)
+exten => s,n,Set(VMGAIN=${IF($["foo${VM_GAIN}"!="foo"]?"g(${VM_GAIN})":"")})
+;
+; If BLKVM_OVERRIDE is set, then someone told us to block calls from going to
+; voicemail. This variable is reset by the answering channel so subsequent
+; transfers will properly function.
+;
+exten => s,n,GotoIf($["foo${DB(${BLKVM_OVERRIDE})}" != "fooTRUE"]?vmx,1)
+;
+; we didn't branch so block this from voicemail
+;
+exten => s,n,Noop(CAME FROM: ${NODEST} - Blocking VM cause of key: ${DB(BLKVM_OVERRIDE)})
+
+
+; If vmx not enabled for the current mode,then jump to normal voicemail behavior
+; also - if not message (no-msg) is requested, straight to voicemail
+;
+exten => vmx,1,GotoIf($["${ARG2}"="NOMESSAGE"]?s-${ARG2},1)
+exten => vmx,n,Set(MODE=${IF($["${ARG2}"="BUSY"]?busy:unavail)})
+exten => vmx,n,GotoIf($["${ARG2}" != "DIRECTDIAL"]?notdirect)
+exten => vmx,n,Set(MODE=${IF($["${REGEX("[b]" ${VM_DDTYPE})}" = "1"]?busy:${MODE})})
+exten => vmx,n(notdirect),Noop(Checking if ext ${ARG1} is enabled: ${DB(AMPUSER/${ARG1}/vmx/${MODE}/state)})
+exten => vmx,n,GotoIf($["${DB(AMPUSER/${ARG1}/vmx/${MODE}/state)}" != "enabled"]?s-${ARG2},1)
+
+; If the required voicemail file does not exist, then abort and go to normal voicemail behavior
+;
+; TODO: there have been errors using System() with jump to 101 where asterisk works fine at the begining and
+;       then starts to jump to 101 even on success. This new mode is being tried with the SYSTEM Status which
+;       returns SUCCESS when the command returned succcessfully with a 0 app return code.
+;
+exten => vmx,n,Macro(get-vmcontext,${ARG1})
+;exten => vmx,n,TrySystem(/bin/ls ${ASTSPOOLDIR}/voicemail/${VMCONTEXT}/${ARG1}/${MODE}.[wW][aA][vV])
+exten => vmx,n,AGI(checksound.agi,${ASTSPOOLDIR}/voicemail/${VMCONTEXT}/${ARG1}/${MODE})
+exten => vmx,n,GotoIf($["${SYSTEMSTATUS}" != "SUCCESS"]?nofile)
+
+; Get the repeat, timeout and loop times to use if they are overriden form the global settings
+;
+exten => vmx,n,Set(LOOPCOUNT=0)
+exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/repeat)}" = "0"]?vmxtime)
+exten => vmx,n,Set(VMX_REPEAT=${DB_RESULT})
+exten => vmx,n(vmxtime),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timeout)}" = "0"]?vmxloops)
+exten => vmx,n,Set(VMX_TIMEOUT=${DB_RESULT})
+exten => vmx,n(vmxloops),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/loops)}" = "0"]?vmxanswer)
+exten => vmx,n,Set(VMX_LOOPS=${DB_RESULT})
+exten => vmx,n(vmxanswer),Answer()
+
+; Now play the users voicemail recording as the basis for their ivr, the Read command will repeat as needed and if it timesout
+; then we go to the timeout. Otherwise handle invalid options by looping until the limit until a valid option is played.
+;
+exten => vmx,n(loopstart),Read(ACTION,${ASTSPOOLDIR}/voicemail/${VMCONTEXT}/${ARG1}/${MODE},1,skip,${VMX_REPEAT},${VMX_TIMEOUT})
+exten => vmx,n,GotoIf($["${EXISTS(${ACTION})}" = "1"]?checkopt)
+
+; If we are here we timed out, go to the required destination
+;
+exten => vmx,n(noopt),Noop(Timeout: going to timeout dest)
+exten => vmx,n,Set(VMX_OPTS=${VMX_OPTS_TIMEOUT})
+exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/vmxopts/timeout)}" = "0"]?chktime)
+exten => vmx,n,Set(VMX_OPTS=${DB_RESULT})
+exten => vmx,n(chktime),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timedest/ext)}" = "0"]?dotime)
+exten => vmx,n,Set(VMX_TIMEDEST_EXT=${DB_RESULT})
+exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timedest/context)}" = "0"]?timepri)
+exten => vmx,n,Set(VMX_TIMEDEST_CONTEXT=${DB_RESULT})
+exten => vmx,n(timepri),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timedest/pri)}" = "0"]?dotime)
+exten => vmx,n,Set(VMX_TIMEDEST_PRI=${DB_RESULT})
+exten => vmx,n(dotime),Goto(${VMX_TIMEDEST_CONTEXT},${VMX_TIMEDEST_EXT},${VMX_TIMEDEST_PRI})
+
+; We got an option, check if the option is defined, or one of the system defaults
+;
+exten => vmx,n(checkopt),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/${ACTION}/ext)}" = "1"]?doopt)
+exten => vmx,n,GotoIf($["${ACTION}" = "0"]?o,1)
+exten => vmx,n,GotoIf($["${ACTION}" = "*"]?adef,1)
+
+; Got invalid option loop until the max
+;
+exten => vmx,n,Set(LOOPCOUNT=$[${LOOPCOUNT} + 1])
+exten => vmx,n,GotoIf($[${LOOPCOUNT} > ${VMX_LOOPS}]?toomany)
+exten => vmx,n,Playback(pm-invalid-option&please-try-again)
+exten => vmx,n,Goto(loopstart)
+
+; tomany: to many invalid options, go to the specified destination
+;
+exten => vmx,n(toomany),Noop(Too Many invalid entries, got to invalid dest)
+exten => vmx,n,Set(VMX_OPTS=${VMX_OPTS_LOOPS})
+exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/vmxopts/loops)}" = "0"]?chkloop)
+exten => vmx,n,Set(VMX_OPTS=${DB_RESULT})
+exten => vmx,n(chkloop),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/loopdest/ext)}" = "0"]?doloop)
+exten => vmx,n,Set(VMX_LOOPDEST_EXT=${DB_RESULT})
+exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/loopdest/context)}" = "0"]?looppri)
+exten => vmx,n,Set(VMX_LOOPDEST_CONTEXT=${DB_RESULT}) ;TODO make configurable per above
+exten => vmx,n(looppri),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/loopdest/pri)}" = "0"]?doloop)
+exten => vmx,n,Set(VMX_LOOPDEST_PRI=${DB_RESULT}) ;TODO make configurable per above
+exten => vmx,n(doloop),Goto(${VMX_LOOPDEST_CONTEXT},${VMX_LOOPDEST_EXT},${VMX_LOOPDEST_PRI})
+
+; doopt: execute the valid option that was chosen
+;
+exten => vmx,n(doopt),Noop(Got a valid option: ${DB_RESULT})
+exten => vmx,n,Set(VMX_EXT=${DB_RESULT})
+;
+; Special case, if this option was to go to voicemail, set options and go
+;
+exten => vmx,n,GotoIf($["${VMX_EXT}" != "dovm"]?getdest)
+exten => vmx,n(vmxopts),Set(VMX_OPTS=${VMX_OPTS_DOVM})
+exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/vmxopts/dovm)}" = "0"]?vmxdovm)
+exten => vmx,n(vmxopts),Set(VMX_OPTS=${DB_RESULT})
+exten => vmx,n(vmxdovm),goto(dovm,1)
+;
+; General case, setup the goto destination and go there (no error checking, its up to the GUI's to assure
+; reasonable values
+;
+exten => vmx,n(getdest),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/${ACTION}/context)}" = "0"]?vmxpri)
+exten => vmx,n,Set(VMX_CONTEXT=${DB_RESULT})
+exten => vmx,n(vmxpri),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/${ACTION}/pri)}" = "0"]?vmxgoto)
+exten => vmx,n,Set(VMX_PRI=${DB_RESULT})
+exten => vmx,n(vmxgoto),Goto(${VMX_CONTEXT},${VMX_EXT},${VMX_PRI})
+
+; If the required voicemail file is not present, then revert to normal voicemail
+; behavior treating as if it was not set
+;
+exten => vmx,n(nofile),Noop(File for mode: ${MODE} does not exist, SYSTEMSTATUS: ${SYSTEMSTATUS}, going to normal voicemail)
+exten => vmx,n,Goto(s-${ARG2},1)
+
+; Drop into voicemail either as a direct destination (in which case VMX_OPTS might be set to something) or
+; if the user timed out or broke out of the loop then VMX_OPTS is always cleared such that an Allison
+; message is played and the caller know's what is going on.
+;
+exten => dovm,1,Noop(VMX Timeout - go to voicemail)
+exten => dovm,n,Voicemail(${ARG1}@${VMCONTEXT},${VMX_OPTS}${VMGAIN}) ; no flags, so allison plays please leave ...
+exten => dovm,n,Goto(exit-${VMSTATUS},1)
+
+exten => s-BUSY,1,NoOp(BUSY voicemail)
+exten => s-BUSY,n,Macro(get-vmcontext,${ARG1})
+exten => s-BUSY,n,Voicemail(${ARG1}@${VMCONTEXT},${VM_OPTS}b${VMGAIN})   ; Voicemail Busy message
+exten => s-BUSY,n,Goto(exit-${VMSTATUS},1)
+
+exten => s-NOMESSAGE,1,NoOp(NOMESSAGE (beeb only) voicemail)
+exten => s-NOMESSAGE,n,Macro(get-vmcontext,${ARG1})
+exten => s-NOMESSAGE,n,Voicemail(${ARG1}@${VMCONTEXT},${VM_OPTS}${VMGAIN})   ; Voicemail Busy message
+exten => s-NOMESSAGE,n,Goto(exit-${VMSTATUS},1)
+
+exten => s-DIRECTDIAL,1,NoOp(DIRECTDIAL voicemail)
+exten => s-DIRECTDIAL,n,Macro(get-vmcontext,${ARG1})
+exten => s-DIRECTDIAL,n,Voicemail(${ARG1}@${VMCONTEXT},${VM_OPTS}${VM_DDTYPE}${VMGAIN})
+exten => s-DIRECTDIAL,n,Goto(exit-${VMSTATUS},1)
+
+exten => _s-.,1,Macro(get-vmcontext,${ARG1})
+exten => _s-.,n,Voicemail(${ARG1}@${VMCONTEXT},${VM_OPTS}u${VMGAIN})     ; Voicemail Unavailable message
+exten => _s-.,n,Goto(exit-${VMSTATUS},1)
+
+; If the user has a 0 option defined, use that for operator zero-out from within voicemail
+; as well to keep it consistant with the menu structure
+;
+exten => o,1,Background(one-moment-please)      ; 0 during vm message will hangup
+exten => o,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/0/ext)}" = "0"]?doopdef)
+
+exten => o,n,Set(VMX_OPDEST_EXT=${DB_RESULT})
+exten => o,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/0/context)}" = "1"]?opcontext)
+exten => o,n,Set(DB_RESULT=${VMX_CONTEXT})
+exten => o,n(opcontext),Set(VMX_OPDEST_CONTEXT=${DB_RESULT})
+exten => o,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/0/pri)}" = "1"]?oppri)
+exten => o,n,Set(DB_RESULT=${VMX_PRI})
+exten => o,n(oppri),Set(VMX_OPDEST_PRI=${DB_RESULT})
+
+exten => o,n,Goto(${VMX_OPDEST_CONTEXT},${VMX_OPDEST_EXT},${VMX_OPDEST_PRI})
+exten => o,n(doopdef),GotoIf($["x${OPERATOR_XTN}"="x"]?nooper:from-internal,${OPERATOR_XTN},1)
+exten => o,n(nooper),GotoIf($["x${FROM_DID}"="x"]?nodid)
+exten => o,n,Dial(Local/${FROM_DID)@from-pstn)
+exten => o,n,Macro(hangup)
+exten => o,n(nodid),Dial(Local/s at from-pstn)
+exten => o,n,Macro(hangup)
+
+; If the user has a * option defined, use that for the * out from within voicemail
+; as well to keep it consistant with the menu structure
+;
+exten => a,1,Macro(get-vmcontext,${ARG1})
+exten => a,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/*/ext)}" = "0"]?adef,1)
+
+exten => a,n,Set(VMX_ADEST_EXT=${DB_RESULT})
+exten => a,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/*/context)}" = "1"]?acontext)
+exten => a,n,Set(DB_RESULT=${VMX_CONTEXT})
+exten => a,n(acontext),Set(VMX_ADEST_CONTEXT=${DB_RESULT})
+exten => a,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/*/pri)}" = "1"]?apri)
+exten => a,n,Set(DB_RESULT=${VMX_PRI})
+exten => a,n(apri),Set(VMX_ADEST_PRI=${DB_RESULT})
+exten => a,n,Goto(${VMX_ADEST_CONTEXT},${VMX_ADEST_EXT},${VMX_ADEST_PRI})
+
+exten => adef,1,VoiceMailMain(${ARG1}@${VMCONTEXT})
+exten => adef,n,Hangup
+
+exten => exit-FAILED,1,Playback(im-sorry&an-error-has-occured)
+exten => exit-FAILED,n,Hangup()
+
+exten => exit-SUCCESS,1,Playback(goodbye)
+exten => exit-SUCCESS,n,Hangup()
+
+exten => exit-USEREXIT,1,Playback(goodbye)
+exten => exit-USEREXIT,n,Hangup()
+
+exten => t,1,Hangup()
+;------------------------------------------------------------------------
+
+;------------------------------------------------------------------------
+; [macro-simple-dial]
+;------------------------------------------------------------------------
+; This macro was derived from macro-exten-vm, which is what is normally used to
+; ring an extension. It has been simplified and designed to never go to voicemail
+; and always return regardless of the DIALSTATUS for any incomplete call.
+;
+; It's current primary purpose is to allow findmefollow ring an extension prior
+; to trying the follow-me ringgroup that is provided.
+;
+; Ring an extension, if the extension is busy or there is no answer, return
+; ARGS: $EXTENSION, $RINGTIME
+;------------------------------------------------------------------------
+[macro-simple-dial]
+exten => s,1,Macro(user-callerid,SKIPTTL) ; already called from follow-me
+
+; FROMCONTEXT was in the original macro-exten-vm where this macro was derived from. A
+; search through all the modules does not come up with any place using this
+; variable, but it is left here as a reminder in case there is functionality
+; that eventually behaves in a certain way as a result of this variable being set
+; and this macro has to masquerade as exten-vm.
+;
+exten => s,n,Set(EXTTOCALL=${ARG1})
+exten => s,n,Set(RT=${ARG2})
+exten => s,n,Set(CFUEXT=${DB(CFU/${EXTTOCALL})})
+exten => s,n,Set(CFBEXT=${DB(CFB/${EXTTOCALL})})
+exten => s,n,Macro(record-enable,${EXTTOCALL},IN)
+
+exten => s,n,Macro(dial,${RT},${DIAL_OPTIONS},${EXTTOCALL})
+
+exten => s,n,Set(PR_DIALSTATUS=${DIALSTATUS})
+
+; if we return, thus no answer, and they have a CFU setting, then  we try that next
+;
+exten => s,n,GosubIf($[$["${PR_DIALSTATUS}"="NOANSWER"] & $["foo${CFUEXT}"!="foo"]]?docfu,1) ; check for CFU in use on no answer
+exten => s,n,GosubIf($[$["${PR_DIALSTATUS}"="BUSY"] & $["foo${CFBEXT}"!="foo"]]?docfb,1) ; check for CFB in use on busy
+exten => s,n,Set(DIALSTATUS=${PR_DIALSTATUS})
+
+; Nothing yet, then go to the end (which will just return, but in case we decide to do something with certain
+; return situations, this is left in.
+;
+exten => s,n,Goto(s-${DIALSTATUS},1)
+
+; Try the Call Forward on No Answer / Unavailable number.
+; We want to try CFU if set, but we want the same ring timer as was set to our call (or do we want the
+; system ringtimer? - probably not). Then if no answer there (assuming it doesn't drop into their vm or
+; something we return, which will have the net effect of returning to the followme setup.)
+;
+; want to avoid going to other follow-me settings here. So check if the CFUEXT is a user and if it is
+; then direct it straight to ext-local (to avoid getting intercepted by findmefollow) otherwise send it
+; to from-internal since it may be an outside line.
+;
+exten => docfu,1,GotoIf( $[ "foo${DB(AMPUSER/${CFUEXT}/device)}" = "foo" ]?chlocal)
+exten => docfu,n,Dial(Local/${CFUEXT}@ext-local,${RT},${DIAL_OPTIONS})
+exten => docfu,n,Return
+exten => docfu,n(chlocal),Dial(Local/${CFUEXT}@from-internal/n,${RT},${DIAL_OPTIONS})
+exten => docfu,n,Return
+
+; Try the Call Forward on Busy number
+exten => docfb,1,GotoIf( $[ "foo${DB(AMPUSER/${CFBEXT}/device)}" = "foo" ]?chlocal)
+exten => docfb,n,Dial(Local/${CFBEXT}@ext-local,${RT},${DIAL_OPTIONS})
+exten => docfb,n,Return
+exten => docfb,n(chlocal),Dial(Local/${CFBEXT}@from-internal/n,${RT},${DIAL_OPTIONS})
+exten => docfb,n,Return
+
+; In all cases of no connection, come here and simply return, since the calling dialplan will
+; decide what to do next
+exten => _s-.,1,NoOp(Extension is reporting ${EXTEN})
+;------------------------------------------------------------------------
+
+
+; get the voicemail context for the user in ARG1
+[macro-get-vmcontext]
+exten => s,1,Set(VMCONTEXT=${DB(AMPUSER/${ARG1}/voicemail)})
+exten => s,2,GotoIf($["foo${VMCONTEXT}" = "foo"]?200:300)
+exten => s,200,Set(VMCONTEXT=default)
+exten => s,300,NoOp()
+
+; For some reason, if I don't run setCIDname, CALLERID(name) will be blank in my AGI
+; ARGS: none
+[macro-fixcid]
+exten => s,1,Set(CALLERID(name)=${CALLERID(name)})
+
+; Ring groups of phones
+; ARGS: comma separated extension list
+; 1 - Ring Group Strategy
+; 2 - ringtimer
+; 3 - prefix
+; 4 - extension list
+[macro-rg-group]
+exten => s,1,Macro(user-callerid,SKIPTTL) ; already called from ringgroup
+exten => s,2,GotoIf($["${CALLERID(name):0:${LEN(${RGPREFIX})}}" != "${RGPREFIX}"]?4:3)  ; check for old prefix
+exten => s,3,Set(CALLERID(name)=${CALLERID(name):${LEN(${RGPREFIX})}}) ; strip off old prefix
+exten => s,4,Set(RGPREFIX=${ARG3})  ; set new prefix
+exten => s,5,Set(CALLERID(name)=${RGPREFIX}${CALLERID(name)})  ; add prefix to callerid name
+exten => s,6,Set(RecordMethod=Group)  ; set new prefix
+exten => s,7,Macro(record-enable,${MACRO_EXTEN},${RecordMethod})
+exten => s,8,Set(RingGroupMethod=${ARG1})     ;
+exten => s,9,Macro(dial,${ARG2},${DIAL_OPTIONS},${ARG4})
+exten => s,10,Set(RingGroupMethod='')     ;
+
+
+;
+; Outgoing channel(s) are busy ... inform the client
+; but use noanswer features like ringgroups don't break by being answered
+; just to play the message.
+;
+[macro-outisbusy]
+exten => s,1,Playback(all-circuits-busy-now,noanswer)
+exten => s,n,Playback(pls-try-call-later,noanswer)
+exten => s,n,Macro(hangupcall)
+
+; What to do on hangup.                                         
+[macro-hangupcall]
+exten => s,1,ResetCDR(w)
+exten => s,n,NoCDR()
+ 
+; Cleanup any remaining RG flag
+;
+exten => s,n,GotoIf($[ "x${USE_CONFIRMATION}" = "x" | "x${RINGGROUP_INDEX}" = "x" | "${CHANNEL}" != "${UNIQCHAN}"]?skiprg)
+exten => s,n,Noop(Cleaning Up Confirmation Flag: RG/${RINGGROUP_INDEX}/${CHANNEL})
+exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL})
+
+; Cleanup any remaining BLKVM flag
+;
+exten => s,n(skiprg),GotoIf($[ "x${BLKVM_BASE}" = "x" | "BLKVM/${BLKVM_BASE}/${CHANNEL}" != "${BLKVM_OVERRIDE}" ]?skipblkvm)
+exten => s,n,Noop(Cleaning Up Block VM Flag: ${BLKVM_OVERRIDE})
+exten => s,n,DBDel(${BLKVM_OVERRIDE})
+
+; Cleanup any remaining FollowMe DND flags
+;
+exten => s,n(skipblkvm),GotoIf($[ "x${FMGRP}" = "x" | "x${FMUNIQUE}" = "x" | "${CHANNEL}" != "${FMUNIQUE}" ]?theend)
+exten => s,n,DBDel(FM/DND/${FMGRP}/${CHANNEL})
+
+exten => s,n(theend),Hangup
+
+[macro-faxreceive]
+exten => s,1,Set(FAXFILE=${ASTSPOOLDIR}/fax/${UNIQUEID}.tif)
+exten => s,2,Set(EMAILADDR=${FAX_RX_EMAIL})
+exten => s,3,rxfax(${FAXFILE})
+exten => s,103,Set(EMAILADDR=${FAX_RX_EMAIL})
+exten => s,104,Goto(3)
+
+; dialout and strip the prefix
+[macro-dialout]
+exten => s,1,Macro(user-callerid,SKIPTTL)
+exten => s,2,GotoIf($["${ECID${CALLERID(number)}}" = ""]?5) 	;check for CID override for exten
+exten => s,3,Set(CALLERID(all)=${ECID${CALLERID(number)}})
+exten => s,4,Goto(7)
+exten => s,5,GotoIf($["${OUTCID_${ARG1}}" = ""]?7) 		;check for CID override for trunk
+exten => s,6,Set(CALLERID(all)=${OUTCID_${ARG1}})
+exten => s,7,Set(length=${LEN(${DIAL_OUT_${ARG1}})})
+exten => s,8,Dial(${OUT_${ARG1}}/${ARG2:${length}})
+exten => s,9,Playtones(congestion)
+exten => s,10,Congestion(5)
+exten => s,109,Macro(outisbusy)
+
+
+; dialout using default OUT trunk - no prefix
+[macro-dialout-default]
+exten => s,1,Macro(user-callerid,SKIPTTL)
+exten => s,2,Macro(record-enable,${CALLERID(number)},OUT)
+exten => s,3,Macro(outbound-callerid,${ARG1})
+exten => s,4,Dial(${OUT}/${ARG1})
+exten => s,5,Playtones(congestion)
+exten => s,6,Congestion(5)
+exten => s,105,Macro(outisbusy)
+
+[macro-dialout-trunk-predial-hook]
+; this macro intentially left blank so it may be safely overwritten for any custom
+; requirements that an installatin may have.
+;
+; MACRO RETURN CODE: ${PREDIAL_HOOK_RET}
+;                    if set to "BYPASS" then this trunk will be skipped
+;
+
+
+; dialout using a trunk, using pattern matching (don't strip any prefix)
+; arg1 = trunk number, arg2 = number, arg3 = route password
+;
+; MODIFIED (PL)
+;
+; Modified both Dial() commands to include the new TRUNK_OPTIONS from the general
+; screen of AMP
+;
+[macro-dialout-trunk]
+exten => s,1,Set(DIAL_TRUNK=${ARG1})
+exten => s,n,Set(DIAL_NUMBER=${ARG2})
+exten => s,n,Set(ROUTE_PASSWD=${ARG3})
+
+exten => s,n,GotoIf($["${ROUTE_PASSWD}" = ""]?noauth) ; arg3 is pattern password
+exten => s,n(auth),Authenticate(${ROUTE_PASSWD})
+exten => s,n(noauth),GotoIf($["x${OUTDISABLE_${ARG1}}" = "xon"]?disabletrunk,1)
+
+; If NODEST is set, clear it. No point in remembering since dialout-trunk will just end in the
+; bit bucket. But if answered by an outside line with transfer capability, we want NODEST to be
+; clear so a subsequent transfer to an internal extension works and goes to voicmail or other
+; destinations.
+;
+exten => s,n,Set(_NODEST=)
+
+exten => s,n,Set(DIAL_TRUNK_OPTIONS=${DIAL_OPTIONS}) // will be reset to TRUNK_OPTIONS if not intra-company
+exten => s,n,Set(GROUP()=OUT_${DIAL_TRUNK})
+exten => s,n,Macro(user-callerid,SKIPTTL)
+exten => s,n,Macro(record-enable,${CALLERID(number)},OUT)
+exten => s,n,GotoIf($["${INTRACOMPANYROUTE}" = "YES"]?skipoutcid) ;Set to YES if treated like internal
+exten => s,n,Set(DIAL_TRUNK_OPTIONS=${TRUNK_OPTIONS})
+exten => s,n,Macro(outbound-callerid,${DIAL_TRUNK})
+exten => s,n(skipoutcid),GotoIf($["${OUTMAXCHANS_${DIAL_TRUNK}}foo" = "foo"]?nomax)
+exten => s,n(checkmax),GotoIf($[ ${GROUP_COUNT(OUT_${DIAL_TRUNK})} > ${OUTMAXCHANS_${DIAL_TRUNK}} ]?chanfull)
+exten => s,n(nomax),AGI(fixlocalprefix) ; this sets DIAL_NUMBER to the proper dial string for this trunk
+exten => s,n,Set(OUTNUM=${OUTPREFIX_${DIAL_TRUNK}}${DIAL_NUMBER}) ; OUTNUM is the final dial number
+exten => s,n,Set(custom=${CUT(OUT_${DIAL_TRUNK},:,1)}) ; Custom trunks are prefixed with "AMP:"
+
+; Back to normal processing, whether intracompany or not.
+; But add the macro-setmusic if we don't want music on this outbound call
+;
+exten => s,n,GotoIf($[$["${MOHCLASS}" = "default"] | $["foo${MOHCLASS}" = "foo"]]?gocall) ; Set to YES if we should pump silence
+exten => s,n,Set(DIAL_TRUNK_OPTIONS=M(setmusic^${MOHCLASS})${DIAL_TRUNK_OPTIONS}) 	; set MoH or off
+
+; This macro call will always be blank and is provided as a hook for customization required prior to making a call
+; such as adding SIP header information or other requirements. All the channel variables from above are present
+;
+exten => s,n(gocall),Macro(dialout-trunk-predial-hook)
+exten => s,n,GotoIf($["${PREDIAL_HOOK_RET}" = "BYPASS"]?bypass,1)
+
+exten => s,n,GotoIf($["${custom}" = "AMP"]?customtrunk)
+exten => s,n,Dial(${OUT_${DIAL_TRUNK}}/${OUTNUM},300,${DIAL_TRUNK_OPTIONS}) ; Regular Trunk Dial
+exten => s,n,Goto(s-${DIALSTATUS},1)
+exten => s,n(customtrunk),Set(pre_num=${CUT(OUT_${DIAL_TRUNK},$,1)})
+exten => s,n,Set(the_num=${CUT(OUT_${DIAL_TRUNK},$,2)}) ; this is where we expect to find string OUTNUM
+exten => s,n,Set(post_num=${CUT(OUT_${DIAL_TRUNK},$,3)})
+exten => s,n,GotoIf($["${the_num}" = "OUTNUM"]?outnum:skipoutnum) ; if we didn't find "OUTNUM", then skip to Dial
+exten => s,n(outnum),Set(the_num=${OUTNUM}) ; replace "OUTNUM" with the actual number to dial
+exten => s,n(skipoutnum),Dial(${pre_num:4}${the_num}${post_num},300,${DIAL_TRUNK_OPTIONS})
+exten => s,n,Goto(s-${DIALSTATUS},1)
+
+exten => s,n(chanfull),Noop(max channels used up)
+
+exten => s-BUSY,1,NoOp(Dial failed due to trunk reporting BUSY - giving up)
+exten => s-BUSY,n,Playtones(busy)
+exten => s-BUSY,n,Busy(20)
+
+exten => s-NOANSWER,1,NoOp(Dial failed due to trunk reporting NOANSWER - giving up)
+exten => s-NOANSWER,n,Playtones(congestion)
+exten => s-NOANSWER,n,Congestion(20)
+
+exten => s-CANCEL,1,NoOp(Dial failed due to trunk reporting CANCEL - giving up)
+exten => s-CANCEL,n,Playtones(congestion)
+exten => s-CANCEL,n,Congestion(20)
+
+exten => _s-.,1,GotoIf($["x${OUTFAIL_${ARG1}}" = "x"]?noreport)
+exten => _s-.,n,AGI(${OUTFAIL_${ARG1}})
+exten => _s-.,n(noreport),Noop(TRUNK Dial failed due to ${DIALSTATUS} - failing through to other trunks)
+
+exten => disabletrunk,1,Noop(TRUNK: ${OUT_${DIAL_TRUNK}} DISABLED - falling through to next trunk)
+exten => bypass,1,Noop(TRUNK: ${OUT_${DIAL_TRUNK}} BYPASSING because dialout-trunk-predial-hook)
+
+exten => h,1,Macro(hangupcall)
+
+; Adds a dynamic agent/member to a Queue
+; Prompts for call-back number - in not entered, uses CIDNum
+[macro-agent-add]
+exten => s,1,Wait(1)
+exten => s,n,Macro(user-callerid,SKIPTTL)
+exten => s,n(a3),Read(CALLBACKNUM,agent-user)  	; get callback number from user
+exten => s,n,GotoIf($["${CALLBACKNUM}" != ""]?a7)	; if user just pressed # or timed out, use cidnum
+exten => s,n(a5),Set(CALLBACKNUM=${AMPUSER})
+exten => s,n,ExecIf($["${CALLBACKNUM}" = ""],Set,CALLBACKNUM=${CALLERID(number)})
+exten => s,n,GotoIf($["${CALLBACKNUM}" = ""]?a3)	; if still no number, start over
+exten => s,n(a7),GotoIf($["${CALLBACKNUM}" = "${ARG1}"]?invalid)	; Error, they put in the queue number
+exten => s,n,ExecIf($["${ARG2}" != ""],Authenticate,${ARG2})
+exten => s,n(a9),AddQueueMember(${ARG1},Local/${CALLBACKNUM}@from-internal/n)	; using chan_local allows us to have agents over trunks
+exten => s,n,UserEvent(Agentlogin,Agent: ${CALLBACKNUM})
+exten => s,n,Wait(1)
+exten => s,n,Playback(agent-loginok&with&extension)
+exten => s,n,SayDigits(${CALLBACKNUM})
+exten => s,n,Hangup()
+exten => s,n+1(invalid),Playback(pbx-invalid)
+exten => s,n,Goto(a3)
+
+
+; Removes a dynamic agent/member from a Queue
+; Prompts for call-back number - in not entered, uses CIDNum
+[macro-agent-del]
+exten => s,1,Wait(1)
+exten => s,n,Macro(user-callerid,SKIPTTL)
+exten => s,n(a3),Read(CALLBACKNUM,agent-user)  	; get callback number from user
+exten => s,n,GotoIf($["${CALLBACKNUM}" = ""]?a5:a7)	; if user just pressed # or timed out, use cidnum
+exten => s,n(a5),Set(CALLBACKNUM=${AMPUSER})
+exten => s,n,ExecIf($["${CALLBACKNUM}" = ""],Set,CALLBACKNUM=${CALLERID(number)})
+exten => s,n,GotoIf($["${CALLBACKNUM}" = ""]?a3)	; if still no number, start over
+exten => s,n(a7),RemoveQueueMember(${ARG1},Local/${CALLBACKNUM}@from-internal/n)
+exten => s,n,UserEvent(RefreshQueue)
+exten => s,n,Wait(1)
+exten => s,n,Playback(agent-loggedoff)
+exten => s,n,Hangup()
+
+; arg1 = trunk number, arg2 = number
+[macro-dialout-enum]
+; Re-written to use enumlookup.agi
+exten => s,1,GotoIf($["${ARG3}" != ""]?PASSWD:NOPASSWD); arg3 is pattern password 
+exten => s,n(PASSWD),Authenticate(${ARG3}) 
+exten => s,n(NOPASSWD),Macro(user-callerid,SKIPTTL) 
+exten => s,n,Macro(record-enable,${CALLERID(number)},OUT)
+exten => s,n,Macro(outbound-callerid,${ARG1})
+exten => s,n,Set(GROUP()=OUT_${ARG1})
+exten => s,n,GotoIf($["${OUTMAXCHANS_${ARG1}}foo" = "foo"]?nomax)
+exten => s,n,GotoIf($[ ${GROUP_COUNT(OUT_${ARG1})} > ${OUTMAXCHANS_${ARG1}} ]?nochans)
+exten => s,n(nomax),Set(DIAL_NUMBER=${ARG2})
+exten => s,n,Set(DIAL_TRUNK=${ARG1})
+exten => s,n,AGI(fixlocalprefix)  ; this sets DIAL_NUMBER to the proper dial string for this trunk
+; Replacement for asterisk's ENUMLOOKUP function
+exten => s,n,AGI(enumlookup.agi)
+; Now we have the variable DIALARR set to a list of URI's that can be called, in order of priority
+; Loop through them trying them in order.
+exten => s,n(dialloop),GotoIf($["foo${DIALARR}"="foo"]?end)
+exten => s,n,Set(TRYDIAL=${CUT(DIALARR,%,1)})
+exten => s,n,Set(DIALARR=${CUT(DIALARR,%,2-)})
+exten => s,n,Dial(${TRYDIAL})
+exten => s,n,NoOp(Dial exited in macro-enum-dialout with ${DIALSTATUS})
+
+; Now, if we're still here, that means the Dial failed for some reason. 
+; If it's CONGESTION or CHANUNAVAIL we want to try again on a different
+; different channel. If there's no more left, the dialloop tag will exit.
+exten => s,n,GotoIf($[ $[ "${DIALSTATUS}" = "CHANUNAVAIL" ] | $[ "${DIALSTATUS}" = "CONGESTION" ] ]?dialloop)
+
+; If we're here, then it's BUSY or NOANSWER or something and well, deal with it.
+exten => s,n(dialfailed),Goto(s-${DIALSTATUS},1)
+
+; Here are the exit points for the macro.
+
+exten => s,n(nochans),NoOp(max channels used up)
+
+exten => s,n(end),NoOp(Exiting macro-dialout-enum)
+
+exten => s-BUSY,1,NoOp(Trunk is reporting BUSY)
+exten => s-BUSY,2,Busy(20)
+
+exten => _s-.,1,NoOp(Dial failed due to ${DIALSTATUS})
+
+[macro-record-enable]
+exten => s,1,GotoIf($[${LEN(${BLINDTRANSFER})} > 0]?2:4)
+exten => s,2,ResetCDR(w)
+exten => s,3,StopMonitor()
+exten => s,4,AGI(recordingcheck,${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},${UNIQUEID})
+exten => s,5,Noop(No recording needed) 
+exten => s,999,MixMonitor(${CALLFILENAME}.wav)
+
+;exten => s,3,BackGround(for-quality-purposes)
+;exten => s,4,BackGround(this-call-may-be)
+;exten => s,5,BackGround(recorded)
+
+; This macro is for dev purposes and just dumps channel/app variables.  Useful when designing new contexts. 
+[macro-dumpvars]
+exten => s,1,Noop(ACCOUNTCODE=${ACCOUNTCODE})
+exten => s,2,Noop(ANSWEREDTIME=${ANSWEREDTIME})
+exten => s,3,Noop(BLINDTRANSFER=${BLINDTRANSFER})
+exten => s,4,Noop(CALLERID=${CALLERID(all)})
+exten => s,5,Noop(CALLERID(name)=${CALLERID(name)})
+exten => s,6,Noop(CALLERID(number)=${CALLERID(number)})
+exten => s,7,Noop(CALLINGPRES=${CALLINGPRES})
+exten => s,8,Noop(CHANNEL=${CHANNEL})
+exten => s,9,Noop(CONTEXT=${CONTEXT})
+exten => s,10,Noop(DATETIME=${DATETIME})
+exten => s,11,Noop(DIALEDPEERNAME=${DIALEDPEERNAME})
+exten => s,12,Noop(DIALEDPEERNUMBER=${DIALEDPEERNUMBER})
+exten => s,13,Noop(DIALEDTIME=${DIALEDTIME})
+exten => s,14,Noop(DIALSTATUS=${DIALSTATUS})
+exten => s,15,Noop(DNID=${DNID})
+exten => s,16,Noop(EPOCH=${EPOCH})
+exten => s,17,Noop(EXTEN=${EXTEN})
+exten => s,18,Noop(HANGUPCAUSE=${HANGUPCAUSE})
+exten => s,19,Noop(INVALID_EXTEN=${INVALID_EXTEN})
+exten => s,20,Noop(LANGUAGE=${LANGUAGE})
+exten => s,21,Noop(MEETMESECS=${MEETMESECS})
+exten => s,22,Noop(PRIORITY=${PRIORITY})
+exten => s,23,Noop(RDNIS=${RDNIS})
+exten => s,24,Noop(SIPDOMAIN=${SIPDOMAIN})
+exten => s,25,Noop(SIP_CODEC=${SIP_CODEC})
+exten => s,26,Noop(SIPCALLID=${SIPCALLID})
+exten => s,27,Noop(SIPUSERAGENT=${SIPUSERAGENT})
+exten => s,29,Noop(TXTCIDNAME=${TXTCIDNAME})
+exten => s,30,Noop(UNIQUEID=${UNIQUEID})
+exten => s,31,Noop(TOUCH_MONITOR=${TOUCH_MONITOR})
+exten => s,32,Noop(MACRO_CONTEXT=${MACRO_CONTEXT})
+exten => s,33,Noop(MACRO_EXTEN=${MACRO_EXTEN})
+exten => s,34,Noop(MACRO_PRIORITY=${MACRO_PRIORITY})
+
+[macro-user-logon]
+; check device type
+exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})
+exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1)
+; get user's extension
+exten => s,3,Set(AMPUSER=${ARG1})
+exten => s,4,GotoIf($["${AMPUSER}" = ""]?5:9)
+exten => s,5,Playback(please-enter-your)
+exten => s,6,Playback(extension)
+exten => s,7,Read(AMPUSER,then-press-pound)
+; get user's password and authenticate
+exten => s,8,Wait(1)
+exten => s,9,Set(AMPUSERPASS=${DB(AMPUSER/${AMPUSER}/password)})
+exten => s,10,GotoIf($[${LEN(${AMPUSERPASS})} = 0]?s-NOPASSWORD,1)
+; do not continue if the user has already logged onto this device
+exten => s,11,Set(DEVICEUSER=${DB(DEVICE/${CALLERID(number)}/user)})
+exten => s,12,GotoIf($["${DEVICEUSER}" = "${AMPUSER}"]?s-ALREADYLOGGEDON,1)
+exten => s,13,Authenticate(${AMPUSERPASS})
+; devices can only be mapped to one user - loggoff anyone else who is here
+exten => s,14,Macro(user-logoff)
+; map user to device
+exten => s,15,Set(AMPUSERDEVICES=${DB(AMPUSER/${AMPUSER}/device)})
+exten => s,16,GotoIf($[${LEN(${AMPUSERDEVICES})} = 0]?18) 
+exten => s,17,Set(AMPUSERDEVICES=${AMPUSERDEVICES}&)
+exten => s,18,Set(AMPUSERDEVICES=${AMPUSERDEVICES}${CALLERID(number)})
+exten => s,19,Set(DB(AMPUSER/${AMPUSER}/device)=${AMPUSERDEVICES})
+; map device to user
+exten => s,20,Set(DB(DEVICE/${CALLERID(number)}/user)=${AMPUSER})
+; create symlink from dummy device mailbox to user's mailbox
+exten => s,21,System(/bin/ln -s ${ASTSPOOLDIR}/voicemail/default/${AMPUSER}/ ${ASTSPOOLDIR}/voicemail/device/${CALLERID(number)})
+
+exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged into)
+exten => s-FIXED,2,Playback(ha/phone)
+exten => s-FIXED,3,SayDigits(${CALLERID(number)})
+exten => s-FIXED,4,Playback(is-curntly-unavail)
+exten => s-FIXED,5,Playback(vm-goodbye)
+exten => s-FIXED,6,Hangup ;TODO should play msg indicated device cannot be logged into 
+
+exten => s-ALREADYLOGGEDON,1,NoOp(This device has already been logged into by this user)
+exten => s-ALREADYLOGGEDON,2,Playback(vm-goodbye)
+exten => s-ALREADYLOGGEDON,3,Hangup ;TODO should play msg indicated device is already logged into 
+
+exten => s-NOPASSWORD,1,NoOp(This extension does not exist or no password is set)
+exten => s-NOPASSWORD,2,Playback(an-error-has-occured)
+exten => s-NOPASSWORD,3,Playback(vm-goodbye)
+exten => s-NOPASSWORD,4,Hangup ;TODO should play msg indicated device is already logged into 
+
+[macro-user-logoff]
+; check device type
+exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})
+exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1)
+; remove entry from user's DEVICE key
+; delete the symlink to user's voicemail box
+exten => s,3,System(rm -f ${ASTSPOOLDIR}/voicemail/device/${CALLERID(number)})
+exten => s,4,Set(DEVAMPUSER=${DB(DEVICE/${CALLERID(number)}/user)})
+exten => s,5,Set(AMPUSERDEVICES=${DB(AMPUSER/${DEVAMPUSER}/device)})
+exten => s,6,AGI(list-item-remove.php,${AMPUSERDEVICES},${CALLERID(number)},AMPUSERDEVICES,&)
+; reset user -> device mapping
+; users can log onto multiple devices, need to just remove device from value
+exten => s,7,Set(DB(AMPUSER/${DEVAMPUSER}/device)=${AMPUSERDEVICES})
+; reset device -> user mapping
+exten => s,8,Set(DEFAULTUSER=${DB(DEVICE/${CALLERID(number)}/default_user)})
+exten => s,9,Set(DB(DEVICE/${CALLERID(number)}/user)=${IF($["${DEFAULTUSER}"=""]?none:${DEFAULTUSER})})
+exten => s,10,Playback(vm-goodbye)
+
+exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged out of)
+exten => s-FIXED,2,Playback(an-error-has-occured)
+exten => s-FIXED,3,Playback(vm-goodbye)
+exten => s-FIXED,4,Hangup ;TODO should play msg indicated device cannot be logged into 
+
+[macro-systemrecording]
+exten => s,1,Goto(${ARG1},1)
+
+exten => dorecord,1,Record(/tmp/${AMPUSER}-ivrrecording:wav)
+exten => dorecord,n,Wait(1)
+exten => dorecord,n,Goto(confmenu,1)
+
+exten => docheck,1,Playback(/tmp/${AMPUSER}-ivrrecording)
+exten => docheck,n,Wait(1)
+exten => docheck,n,Goto(confmenu,1)
+
+exten => confmenu,1,Background(to-listen-to-it&press-1&to-rerecord-it&press-star,m,${LANGUAGE},macro-systemrecording)
+exten => confmenu,n,Read(RECRESULT,,1,,,4)
+exten => confmenu,n,GotoIf($["x${RECRESULT}"="x*"]?dorecord,1)
+exten => confmenu,n,GotoIf($["x${RECRESULT}"="x1"]?docheck,1)
+exten => confmenu,n,Goto(1)
+
+exten => 1,1,Goto(docheck,1)
+exten => *,1,Goto(dorecord,1)
+
+exten => t,1,Playback(goodbye)
+exten => t,n,Hangup
+
+exten => i,1,Playback(pm-invalid-option)
+exten => i,n,Goto(confmenu,1)
+
+exten => h,1,Hangup
+
+
+;
+; ############################################################################
+; CallerID Handling
+; ############################################################################
+
+;sets the callerid of the device to that of the logged in user
+;
+; ${AMPUSER} is set upon return to the real user despite any aliasing that may
+; have been set as a result of the AMPUSER/<nnn>/cidnum field. This is used by
+; features like DND, CF, etc. to set the proper structure on aliased instructions
+;
+[macro-user-callerid]
+exten => s,1,Noop(user-callerid: ${CALLERID(name)} ${CALLERID(number)})
+
+; make sure AMPUSER is set if it doesn't get set below
+;
+exten => s,n,Set(AMPUSER=${IF($["foo${AMPUSER}" = "foo"]?${CALLERID(number)}:${AMPUSER})})
+exten => s,n,GotoIf($["${CHANNEL:0:5}" = "Local"]?report) 
+exten => s,n,GotoIf($["${REALCALLERIDNUM:1:2}" != ""]?start)
+exten => s,n,Set(REALCALLERIDNUM=${CALLERID(number)})
+exten => s,n(start),NoOp(REALCALLERIDNUM is ${REALCALLERIDNUM})
+exten => s,n,Set(AMPUSER=${DB(DEVICE/${REALCALLERIDNUM}/user)})
+exten => s,n,Set(AMPUSERCIDNAME=${DB(AMPUSER/${AMPUSER}/cidname)})
+exten => s,n,GotoIf($["x${AMPUSERCIDNAME:1:2}" = "x"]?report) 
+
+; user may masquerade as a different user internally, so set the internal cid as indicated
+; but keep the REALCALLERID which is used to determine their true identify and lookup info
+; during outbound calls.
+;
+exten => s,n,Set(AMPUSERCID=${IF($["${DB_EXISTS(AMPUSER/${AMPUSER}/cidnum)}" = "1"]?${DB_RESULT}:${AMPUSER})})
+exten => s,n,Set(CALLERID(all)="${AMPUSERCIDNAME}" <${AMPUSERCID}>)
+exten => s,n,Set(REALCALLERIDNUM=${DB(DEVICE/${REALCALLERIDNUM}/user)})
+exten => s,n(report),Noop(TTL: ${TTL} ARG1: ${ARG1})
+exten => s,n,GotoIf($[ "${ARG1}" = "SKIPTTL" ]?continue)
+exten => s,n(report2),Set(__TTL=${IF($["foo${TTL}" = "foo"]?64:$[ ${TTL} - 1 ])})
+exten => s,n,GotoIf($[ ${TTL} > 0 ]?continue)
+exten => s,n,Wait(${RINGTIMER}) ; wait for a while, to give it a chance to be picked up by voicemail
+exten => s,n,Answer()
+exten => s,n,Wait(2)
+exten => s,n,Playback(im-sorry&an-error-has-occured&with&call-forwarding)
+exten => s,n,Macro(hangupcall)
+exten => s,n,Congestion()
+exten => s,n(continue),NoOp(Using CallerID ${CALLERID(all)})
+exten => h,1,Macro(hangupcall)
+
+; overrides callerid out trunks
+; arg1 is trunk
+; macro-user-callerid should be called _before_ using this macro
+[macro-outbound-callerid]
+; Keep the original CallerID number, for failover to the next trunk.
+exten => s,1,GotoIf($["${REALCALLERIDNUM:1:2}" != ""]?start)
+exten => s,n,Set(REALCALLERIDNUM=${CALLERID(number)})
+exten => s,n(start),NoOp(REALCALLERIDNUM is ${REALCALLERIDNUM})
+
+; If this came through a ringgroup or CF, then we want to retain original CID unless
+; OUTKEEPCID_${trunknum} is set.
+;
+exten => s,n,GotoIf($["${KEEPCID}" != "TRUE"]?normcid) ;Set to TRUE if coming from ringgroups, CF, etc.
+exten => s,n,GotoIf($["x${OUTKEEPCID_${ARG1}}" = "xon"]?normcid)
+exten => s,n,GotoIf($["foo${REALCALLERIDNUM}" = "foo"]?normcid) ;if not set to anything, go through normal processing
+exten => s,n,Set(USEROUTCID=${REALCALLERIDNUM})
+
+; We now have to make sure the CID is valid. If we find an AMPUSER with the same CID, we assume it is an internal 
+; call (would be quite a conincidence if not) and go through the normal processing to get that CID. If a device 
+; is set for this CID, then it must be internal 
+; 
+exten => s,n,GotoIf($["foo${DB(AMPUSER/${REALCALLERIDNUM}/device)}" = "foo"]?bypass:normcid) 
+
+exten => s,n(normcid),Set(USEROUTCID=${DB(AMPUSER/${REALCALLERIDNUM}/outboundcid)})
+exten => s,n(bypass),Set(EMERGENCYCID=${DB(DEVICE/${REALCALLERIDNUM}/emergency_cid)})
+exten => s,n,Set(TRUNKOUTCID=${OUTCID_${ARG1}})
+exten => s,n,GotoIf($["${EMERGENCYROUTE:1:2}" = ""]?trunkcid) ; check EMERGENCY ROUTE
+exten => s,n,GotoIf($["${EMERGENCYCID:1:2}" = ""]?trunkcid) ; empty EMERGENCY CID, so default back to trunk
+exten => s,n,Set(CALLERID(all)=${EMERGENCYCID}) ; emergency cid for device
+exten => s,n,Goto(report)
+exten => s,n(trunkcid),GotoIf($["${TRUNKOUTCID:1:2}" = ""]?usercid)  ;check for CID override for trunk (global var)
+exten => s,n,Set(CALLERID(all)=${TRUNKOUTCID})
+exten => s,n(usercid),GotoIf($["${USEROUTCID:1:2}" = ""]?report) ; check CID override for extension
+exten => s,n,Set(CALLERID(all)=${USEROUTCID})
+exten => s,n,GotoIf($["x${CALLERID(name)}"!="xhidden"]?report:hidecid) ; check CID blocking for extension
+exten => s,n(hidecid),SetCallerPres(prohib_passed_screen) ; Only works with ISDN (T1/E1/BRI)
+exten => s,n(report),NoOp(CallerID set to ${CALLERID(all)})
+
+; Privacy Manager Macro makes sure that any calls that don't pass the privacy manager are presented
+; with congestion since there have been observed cases of the call continuing if not stopped with a 
+; congestion, and this provides a slightly more friendly 'sorry' message in case the user is
+; legitamately trying to be cooperative. 
+;
+; Note: the following options are configurable in privacy.conf:
+;
+;	maxretries = 3 ; default value, number of retries before failing
+;	minlength = 10 ; default value, number of digits to be accepted as valid CID
+;
+[macro-privacy-mgr]
+exten => s,1,Set(KEEPCID=${CALLERID(num)})
+exten => s,n,GotoIf($["foo${CALLERID(num):0:1}"="foo+"]?CIDTEST2:CIDTEST1)
+exten => s,n(CIDTEST1),Set(TESTCID=${MATH(1+${CALLERID(num)})})
+exten => s,n,Goto(TESTRESULT)
+exten => s,n(CIDTEST2),Set(TESTCID=${MATH(1+${CALLERID(num):1})})
+exten => s,n(TESTRESULT),GotoIf($["foo${TESTCID}"="foo"]?CLEARCID:PRIVMGR)
+exten => s,n(CLEARCID),Set(CALLERID(num)=)
+exten => s,n(PRIVMGR),PrivacyManager()
+exten => s,n,GotoIf($["${PRIVACYMGRSTATUS}"="FAILED"]?fail)
+exten => s,n,SetCallerPres(allowed_passed_screen); stop gap until app_privacy.c clears unavailble bit
+exten => s,PRIVMGR+101(fail),Noop(STATUS: ${PRIVACYMGRSTATUS} CID: ${CALLERID(num)} ${CALLERID(name)} CALLPRES: ${CALLLINGPRES})
+exten => s,n,Playback(sorry-youre-having-problems)
+exten => s,n,Playback(goodbye)
+exten => s,n,Playtones(congestion)
+exten => s,n,Congestion(5)
+
+
+
+; Text-To-Speech related macros
+; These all follow common actions.  First try to playback a file "tts/custom-md5" 
+; where "md5" is the md5() of whatever is going to be played. If that doesn't exist,
+; try to playback using macro-tts-sayXXXXX (where XXXXX is text/digits/etc, same as
+; the macro below). If that macro exits with MACRO_OFFSET=100, then it's done, 
+; therwise, fallback to the default asterisk method. 
+;
+; say text is purely for text-to-speech, there is no fallback
+[macro-saytext]
+exten => s,1,Noop(Trying custom SayText playback for "${ARG1}")
+exten => s,n,Playback(tts/custom-${MD5(${ARG1})})
+exten => s,n,GotoIf($["${PLAYBACKSTATUS}"="SUCCESS"]?done)
+; call tts-saytext. This should set MACRO_OFFSET=101 if it was successful
+exten => s,n(tts),Macro(tts-saytext,${ARG1},${ARG2},${ARG3})
+exten => s,n,Noop(No text-to-speech handler for SayText, cannot say "${ARG1}")
+exten => s,n,Goto(done)
+exten => s,tts+101,Noop(tts handled saytext)
+
+; say name is for saying names typically, but fallsback to using SayAlpha
+; (saying the word letter-by-letter)
+[macro-sayname]
+exten => s,1,Noop(Trying custom SayName playback for "${ARG1}")
+exten => s,n,Playback(tts/custom-${MD5(${ARG1})})
+exten => s,n,GotoIf($["${PLAYBACKSTATUS}"="SUCCESS"]?done)
+; call tts-sayalpha. This should set MACRO_OFFSET=101 if it was successful
+exten => s,n(tts),Macro(tts-sayalpha,${ARG1},${ARG2},${ARG3})
+exten => s,n,SayAlpha(${ARG1})
+exten => s,n,Goto(done)
+exten => s,tts+101,Noop(tts handled sayname)
+
+; Say number is for saying numbers (eg "one thousand forty six") 
+[macro-saynumber]
+exten => s,1,Noop(Trying custom SayNumber playback for "${ARG1}")
+exten => s,n,Playback(tts/custom-${MD5(${ARG1})})
+exten => s,n,GotoIf($["${PLAYBACKSTATUS}"="SUCCESS"]?done)
+; call tts-saynumber. This should set MACRO_OFFSET=101 if it was successful
+exten => s,n(tts),Macro(tts-saynumber,${ARG1},${ARG2},${ARG3})
+exten => s,n,SayNumber(${ARG1})
+exten => s,n,Goto(done)
+exten => s,tts+101,Noop(tts handled saynumber)
+
+; Say digits is for saying digits one-by-one (eg, "one zero four six")
+[macro-saydigits]
+exten => s,1,Noop(Trying custom SayDigits playback for "${ARG1}")
+exten => s,n,Playback(tts/custom-${MD5(${ARG1})})
+exten => s,n,GotoIf($["${PLAYBACKSTATUS}"="SUCCESS"]?done)
+; call tts-saydigits. This should set MACRO_OFFSET=101 if it was successful
+exten => s,n(tts),Macro(tts-saydigits,${ARG1},${ARG2},${ARG3})
+exten => s,n,SayDigits(${ARG1})
+exten => s,n,Goto(done)
+
+
+;
+; ############################################################################
+; Inbound Contexts [from]
+; ############################################################################
+
+[from-sip-external]
+;give external sip users congestion and hangup
+; Yes. This is _really_ meant to be _. - I know asterisk whinges about it, but 
+; I do know what I'm doing. This is correct.
+exten => _.,1,NoOp(Received incoming SIP connection from unknown peer to ${EXTEN})
+exten => _.,n,Set(DID=${IF($["${EXTEN:1:2}"=""]?s:${EXTEN})})
+exten => _.,n,Goto(s,1)
+exten => s,1,GotoIf($["${ALLOW_SIP_ANON}"="yes"]?from-trunk,${DID},1)
+exten => s,n,Set(TIMEOUT(absolute)=15)
+exten => s,n,Answer
+exten => s,n,Wait(2)
+exten => s,n,Playback(ss-noservice)
+exten => s,n,Playtones(congestion)
+exten => s,n,Congestion(5)
+exten => h,1,NoOp(Hangup)
+exten => i,1,NoOp(Invalid)
+exten => t,1,NoOp(Timeout)
+
+[from-internal-xfer]
+; applications are now mostly all found in from-internal-additional in _custom.conf
+include => parkedcalls
+include => from-internal-custom
+;allow phones to dial other extensions
+include => ext-fax
+;allow phones to access generated contexts
+;
+; MODIFIED (PL)
+;
+; Currently the include for findmefollow is being auto-generated before ext-local which is the desired behavior.
+; However, I haven't been able to do anything that I know of to force this. We need to determine if it should
+; be hardcoded into here to make sure it doesn't change with some configuration. For now I will leave it out
+; until we can discuss this.
+;
+include => ext-local-confirm
+include => findmefollow-ringallv2
+include => from-internal-additional
+; This causes grief with '#' transfers, commenting out for the moment.
+; include => bad-number
+exten => s,1,Macro(hangupcall)
+exten => h,1,Macro(hangupcall)
+
+[from-internal]
+include => from-internal-xfer
+include => bad-number
+
+[from-zaptel]
+exten => _X.,1,Set(DID=${EXTEN})
+exten => _X.,n,Goto(s,1)
+exten => s,1,NoOp(Entering from-zaptel with DID == ${DID})
+; Some trunks _require_ a RINGING be sent before an Answer. 
+exten => s,n,Ringing()
+; If ($did == "") { $did = "s"; }
+exten => s,n,Set(DID=${IF($["${DID}"= ""]?s:${DID})})
+exten => s,n,NoOp(DID is now ${DID})
+exten => s,n,GotoIf($["${CHANNEL:0:3}"="Zap"]?zapok:notzap)
+exten => s,n(notzap),Goto(from-pstn,${DID},1)
+; If there's no ext-did,s,1, that means there's not a no did/no cid route. Hangup.
+exten => s,n,Macro(hangup)
+exten => s,n(zapok),NoOp(Is a Zaptel Channel)
+exten => s,n,Set(CHAN=${CHANNEL:4})
+exten => s,n,Set(CHAN=${CUT(CHAN,-,1)})
+exten => s,n,Macro(from-zaptel-${CHAN},${DID},1)
+; If nothing there, then treat it as a DID
+exten => s,n,NoOp(Returned from Macro from-zaptel-${CHAN})
+exten => s,n,Goto(from-pstn,${DID},1)
+exten => fax,1,Goto(ext-fax,in_fax,1)
+
+;------------------------------------------------------------------------
+; [macro-setmusic]
+;------------------------------------------------------------------------
+; CONTEXT:      macro-setmusic
+; PURPOSE:      to turn off moh on routes where it is not desired
+;
+;------------------------------------------------------------------------
+[macro-setmusic]
+exten => s,1,NoOp(Setting Outbound Route MoH To: ${ARG1})
+exten => s,2,SetMusicOnHold(${ARG1})
+;------------------------------------------------------------------------
+
+; ##########################################
+; ## Ring Groups with Confirmation macros ##
+; ##########################################
+; Used by followme and ringgroups
+
+;------------------------------------------------------------------------
+; [macro-dial-confirm]
+;------------------------------------------------------------------------
+; This has now been incorporated into dialparties. It still only works with ringall
+; and ringall-prim strategies. Have not investigated why it doesn't work with
+; hunt and memory hunt.
+;
+;------------------------------------------------------------------------
+[macro-dial-confirm]
+; This was written to make it easy to use macro-dial-confirm instead of macro-dial in generated dialplans.
+; This takes the same paramaters, with an additional paramater of the ring group Number
+; ARG1 is the timeout
+; ARG2 is the DIAL_OPTIONS
+; ARG3 is a list of xtns to call - 203-222-240-123123123#-211
+; ARG4 is the ring group number
+
+; This sets a unique value to indicate that the channel is ringing. This is used for warning slow
+; users that the call has already been picked up.
+;
+exten => s,1,Set(DB(RG/${ARG4}/${CHANNEL})=RINGING)
+
+; We need to keep that channel variable, because it'll change when we do this dial, so set it to
+; fallthrough to every sibling.
+;
+exten => s,n,Set(__UNIQCHAN=${CHANNEL})
+
+; The calling ringgroup should have set RingGroupMethod appropriately. We need to set two
+; additional parameters:
+;
+; USE_CONFIRMATION, RINGGROUP_INDEX
+;
+; Thse are passed to inform dialparties to place external calls through the [grps] context
+;
+exten => s,n,Set(USE_CONFIRMATION=TRUE)
+exten => s,n,Set(RINGGROUP_INDEX=${ARG4})
+exten => s,n,Set(ARG4=) ; otherwise it gets passed to dialparties.agi which processes it (prob bug) 
+
+exten => s,n,Macro(dial,${ARG1},${ARG2},${ARG3})
+
+; delete the variable, if we are here, we are done trying to dial and it may have been left around
+;
+exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL})
+exten => s,n,Set(USE_CONFIRMATION=)
+exten => s,n,Set(RINGGROUP_INDEX=)
+;------------------------------------------------------------------------
+
+;------------------------------------------------------------------------
+; [macro-auto-confirm]
+;------------------------------------------------------------------------
+; This macro is called from ext-local-confirm to auto-confirm a call so that other extensions
+; are aware that the call has been answered.
+;
+;------------------------------------------------------------------------
+[macro-auto-confirm]
+exten => s,1,Set(__MACRO_RESULT=)
+exten => s,n,DBDel(${BLKVM_OVERRIDE})
+exten => s,n,DBDel(RG/${ARG1}/${UNIQCHAN})
+
+;------------------------------------------------------------------------
+; [macro-auto-blkvm]
+;------------------------------------------------------------------------
+; This macro is called for any extension dialed form a queue, ringgroup
+; or followme, so that the answering extension can clear the voicemail block
+; override allow subsequent transfers to properly operate.
+;
+;------------------------------------------------------------------------
+[macro-auto-blkvm]
+exten => s,1,Set(__MACRO_RESULT=)
+exten => s,n,DBDel(${BLKVM_OVERRIDE})
+
+;------------------------------------------------------------------------
+; [ext-local-confirm]
+;------------------------------------------------------------------------
+; If call confirm is being used in a ringgroup, then calls that do not require confirmation are sent
+; to this extension instead of straight to the device.
+;
+; The sole purpose of sending them here is to make sure we run Macro(auto-confirm) if this
+; extension answers the line. This takes care of clearing the database key that is used to inform
+; other potential late comers that the extension has been answered by someone else.
+;
+; ALERT_INFO is deprecated in Asterisk 1.4 but still used throughout the FreePBX dialplan and
+; usually set by dialparties.agi. This allows ineritance. Since no dialparties.agi here, set the
+; header if it is set.
+;
+;------------------------------------------------------------------------
+[ext-local-confirm]
+exten => _LC-.,1,Noop(IN ext-local-confirm with - RT: ${RT}, RG_IDX: ${RG_IDX})
+exten => _LC-.,n,GotoIf($["x${ALERT_INFO}"="x"]?godial)
+exten => _LC-.,n,SIPAddHeader(Alert-Info: ${ALERT_INFO})
+exten => _LC-.,n(godial),dial(${DB(DEVICE/${EXTEN:3}/dial)},${RT},M(auto-confirm^${RG_IDX})${DIAL_OPTIONS})
+
+;------------------------------------------------------------------------
+; [macro-confirm]
+;------------------------------------------------------------------------
+; CONTEXT:      macro-confirm                                                                                                              
+; PURPOSE:      added default message if none supplied
+;
+; Follom-Me and Ringgroups provide an option to supply a message to be
+; played as part of the confirmation. These changes have added a default
+; message if none is supplied.
+;
+;------------------------------------------------------------------------
+[macro-confirm]
+exten => s,1,Set(LOOPCOUNT=0)
+exten => s,n,Noop(CALLCONFIRMCID: ${CALLCONFIRMCID})
+
+; We set ABORT rather than CONTINUE, as we want the server to forget about this channel 
+; if it's declined, hung up, or timed out. We don't want it to continue on to the next
+; step in the dialplan, which could be anything!
+exten => s,n,Set(__MACRO_RESULT=ABORT)
+
+; ARG1 is the announcement to play to tell the user that they've got a call they need
+; to confirm. Something along the lines of 'You have an incoming call. Press 1 to accept, 9 to reject'
+exten => s,n,Set(MSG1=${IF($["foo${ARG1}" != "foo"]?${ARG1}:"incoming-call-1-accept-2-decline")})
+exten => s,n(start),Read(INPUT,${MSG1},1,,1,5)
+
+; So. We've now read something, or nothing. We should check to make sure that the call hasn't
+; already been answered by someone else. If it has, send this call to toolate
+exten => s,n,GotoIf(${DB_EXISTS(RG/${ARG3}/${UNIQCHAN})}?check:toolate)
+
+; We passed that test, so it means the call hasn't been answered. Has this user pushed 1? If so,
+; then go to OK.
+exten => s,n(check),GotoIf($["${INPUT}"="1"]?ok)
+
+; If they've pushed 9, then they definately don't want the call. Just pretend there was no response
+; and go to noanswer (or 2 since that will be default for asterisk)
+exten => s,n,GotoIf($["${INPUT}"="9"]?noanswer)
+exten => s,n,GotoIf($["${INPUT}"="2"]?noanswer)
+exten => s,n,GotoIf($["${INPUT}"="3"]?playcid)
+
+; Increment LOOPCOUNT, and check to make sure we haven't played it 5 times by now. We assume that
+; the person is able to push '1' in a reasonably short time.
+exten => s,n,Set(LOOPCOUNT=$[ ${LOOPCOUNT} + 1 ])
+exten => s,n,GotoIf($[ ${LOOPCOUNT} < 5 ]?start)
+
+; If we're here, that means we've played it MORE than 5 times. Set __MACRO_RESULT=ABORT, well, just 
+; coz, and goto fin, which is the last line, meaning it returns to the previous Dial, and pretends as
+; if nothing has happened.
+exten => s,n(noanswer),Set(__MACRO_RESULT=ABORT)
+exten => s,n,Goto(fin)
+
+; Test play callerid
+;
+exten => s,n(playcid),Noop(Playing CID: ${CALLCONFIRMCID})
+exten => s,n,SayDigits(${CALLCONFIRMCID})
+exten => s,n,Goto(start)
+
+; If we're here, it's because the call was already accepted by someone else.
+exten => s,n(toolate),Set(MSG2=${IF($["foo${ARG2}" != "foo"]?${ARG2}:"incoming-call-no-longer-avail")})
+exten => s,n,Playback(${MSG2})
+exten => s,n,Goto(noanswer)
+
+; If we made it here, it's because the call _WAS_ accepted, AND it's still ringing. We delete the
+; database entry (so that the DB_EXISTS line above will trigger a 'toolate' jump), and set the 
+; MACRO_RESULT variable to NOTHING. This is the magic string that joins both legs of the call together
+exten => s,n(ok),DBDel(RG/${ARG3}/${UNIQCHAN})
+exten => s,n,DBDel(${BLKVM_OVERRIDE})
+exten => s,n,Set(__MACRO_RESULT=)
+
+; The end.
+exten => s,n(fin),NoOp(Finished)
+exten => h,1,Noop(Hangup Extension in macro-confirm)
+exten => h,n,Macro(hangupcall)
+
+;------------------------------------------------------------------------
+
+;------------------------------------------------------------------------
+; [findmefollow-ringallv2]
+;------------------------------------------------------------------------
+; This context, to be included in from-internal, implements the PreRing part of findmefollow
+; as well as the GroupRing part. It also communicates between the two so that if DND is set
+; on the primary extension, and mastermode is enabled, then the other extensions will not ring
+;
+;------------------------------------------------------------------------
+[findmefollow-ringallv2]
+exten => _FMPR-.,1,Noop(In FMPR ${FMGRP} with ${EXTEN:5})
+exten => _FMPR-.,n,Set(RingGroupMethod=)
+exten => _FMPR-.,n,Set(USE_CONFIRMATION=)
+exten => _FMPR-.,n,Set(RINGGROUP_INDEX=)
+exten => _FMPR-.,n,Macro(simple-dial,${EXTEN:5},${FMREALPRERING})
+exten => _FMPR-.,n,GotoIf($["${DIALSTATUS}" != "BUSY"]?nodnd)
+exten => _FMPR-.,n,Set(DB(FM/DND/${FMGRP}/${FMUNIQUE})=DND)
+exten => _FMPR-.,n(nodnd),Noop(Ending FMPR ${FMGRP} with ${EXTEN:5} and dialstatus ${DIALSTATUS})
+exten => _FMPR-.,n,Hangup()
+
+exten => _FMGL-.,1,Noop(In FMGL ${FMGRP} with ${EXTEN:5})
+exten => _FMGL-.,n,GotoIf($["${DB(FM/DND/${FMGRP}/${FMUNIQUE})}" = "DND"]?dodnd)
+exten => _FMGL-.,n,Wait(1)
+exten => _FMGL-.,n,GotoIf($["${DB(FM/DND/${FMGRP}/${FMUNIQUE})}" = "DND"]?dodnd)
+exten => _FMGL-.,n,Wait(1)
+exten => _FMGL-.,n,GotoIf($["${DB(FM/DND/${FMGRP}/${FMUNIQUE})}" = "DND"]?dodnd)
+exten => _FMGL-.,n,Wait(${FMPRERING})
+exten => _FMGL-.,n,GotoIf($["${DB(FM/DND/${FMGRP}/${FMUNIQUE})}" = "DND"]?dodnd)
+exten => _FMGL-.,n,DBDel(FM/DND/${FMGRP}/${FMUNIQUE})
+exten => _FMGL-.,n(dodial),Macro(dial,${FMGRPTIME},${DIAL_OPTIONS},${EXTEN:5})
+exten => _FMGL-.,n,Noop(Ending FMGL ${FMGRP} with ${EXTEN:5} and dialstatus ${DIALSTATUS})
+exten => _FMGL-.,n,Hangup()
+exten => _FMGL-.,n+10(dodnd),DBDel(FM/DND/${FMGRP}/${FMUNIQUE})
+exten => _FMGL-.,n,GotoIf($["${FMPRIME}" = "FALSE"]?dodial)
+exten => _FMGL-.,n,Noop(Got DND in FMGL ${FMGRP} with ${EXTEN:5} in ${RingGroupMethod} mode, aborting)
+exten => _FMGL-.,n,Hangup()
+
+;------------------------------------------------------------------------
+
+; ############################################################################
+; Extension Contexts [ext]
+; ############################################################################
+
+[ext-fax]
+exten => s,1,Answer
+exten => s,2,Goto(in_fax,1)
+exten => in_fax,1,StopPlayTones  
+exten => in_fax,2,GotoIf($["${FAX_RX}" = "system"]?3:analog_fax,1)
+exten => in_fax,3,Macro(faxreceive)
+exten => in_fax,4,Hangup
+exten => analog_fax,1,GotoIf($["${FAX_RX}" = "disabled"]?4:2)  ;if fax is disabled, just hang up
+exten => analog_fax,2,Set(DIAL=${DB(DEVICE/${FAX_RX}/dial)});
+exten => analog_fax,3,Dial(${DIAL},20,d)
+exten => analog_fax,4,Hangup
+;exten => out_fax,1,wait(7)
+exten => out_fax,1,txfax(${TXFAX_NAME},caller)
+exten => out_fax,2,Hangup
+exten => h,1,system(/var/lib/asterisk/bin/fax-process.pl --to ${EMAILADDR} --from ${FAX_RX_FROM} --subject "Fax from ${URIENCODE(${CALLERID(number)})} ${URIENCODE(${CALLERID(name)})}" --attachment fax_${URIENCODE(${CALLERID(number)})}.pdf --type application/pdf --file ${FAXFILE});
+exten => h,2,Hangup()
+
+;this is where parked calls go if they time-out.  Should probably re-ring
+[default]
+include => ext-local
+exten => s,1,Playback(vm-goodbye)
+exten => s,2,Macro(hangupcall)

Added: freepbx-modules/trunk/modules/core/etc/iax.conf
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/etc/iax.conf?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/etc/iax.conf (added)
+++ freepbx-modules/trunk/modules/core/etc/iax.conf Mon Apr  7 13:18:05 2008
@@ -1,0 +1,16 @@
+[general]
+bindport = 4569           ; Port to bind to (IAX is 4569)
+bindaddr = 0.0.0.0    ; Address to bind to (all addresses on machine)
+disallow=all
+allow=ulaw
+allow=alaw
+allow=gsm
+mailboxdetail=yes
+
+#include iax_general_custom.conf
+#include iax_registrations_custom.conf
+#include iax_registrations.conf
+#include iax_custom.conf
+#include iax_additional.conf
+#include iax_custom_post.conf
+

Added: freepbx-modules/trunk/modules/core/etc/sip.conf
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/etc/sip.conf?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/etc/sip.conf (added)
+++ freepbx-modules/trunk/modules/core/etc/sip.conf Mon Apr  7 13:18:05 2008
@@ -1,0 +1,42 @@
+; Note: If your SIP devices are behind a NAT and your Asterisk
+;  server isn't, try adding "nat=1" to each peer definition to
+;  solve translation problems.
+
+[general]
+#include sip_general_additional.conf
+
+bindport = 5060           ; Port to bind to (SIP is 5060)
+bindaddr = 0.0.0.0    ; Address to bind to (all addresses on machine)
+disallow=all
+allow=ulaw
+allow=alaw
+; If you need to answer unauthenticated calls, you should change this
+; next line to 'from-trunk', rather than 'from-sip-external'.
+; You'll know this is happening if when you call in you get a message
+; saying "The number you have dialed is not in service. Please check the
+; number and try again."
+context = from-sip-external ; Send unknown SIP callers to this context
+callerid = Unknown
+tos=0x68
+
+; Reported as required for Asterisk 1.4
+notifyringing=yes
+notifyhold=yes
+limitonpeers=yes
+
+; enable and force the sip jitterbuffer. If these settings are desired
+; they should be set in the sip_general_custom.conf file as this file
+; will get overwritten during reloads and upgrades.
+;
+; jbenable=yes
+; jbforce=yes
+
+; #, in this configuration file, is NOT A COMMENT. This is exactly
+; how it should be.
+#include sip_general_custom.conf
+#include sip_nat.conf
+#include sip_registrations_custom.conf
+#include sip_registrations.conf
+#include sip_custom.conf
+#include sip_additional.conf
+#include sip_custom_post.conf

Added: freepbx-modules/trunk/modules/core/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/functions.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/functions.inc.php (added)
+++ freepbx-modules/trunk/modules/core/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,3219 @@
+<?php
+
+// The destinations this module provides
+// returns a associative arrays with keys 'destination' and 'description'
+function core_destinations() {
+	//static destinations
+	$extens = array();
+	$category = 'Terminate Call';
+	$extens[] = array('destination' => 'app-blackhole,hangup,1', 'description' => 'Hangup', 'category' => $category);
+	$extens[] = array('destination' => 'app-blackhole,congestion,1', 'description' => 'Congestion', 'category' => $category);
+	$extens[] = array('destination' => 'app-blackhole,busy,1', 'description' => 'Busy', 'category' => $category);
+	$extens[] = array('destination' => 'app-blackhole,zapateller,1', 'description' => 'Play SIT Tone (Zapateller)', 'category' => $category);
+	$extens[] = array('destination' => 'app-blackhole,musiconhold,1', 'description' => 'Put caller on hold forever', 'category' => $category);
+	
+	//get the list of meetmes
+	$results = core_users_list();
+	
+	if (isset($results) && function_exists('voicemail_getVoicemail')) {
+		//get voicemail
+		$uservm = voicemail_getVoicemail();
+		$vmcontexts = array_keys($uservm);
+		foreach ($results as $thisext) {
+			$extnum = $thisext[0];
+			// search vm contexts for this extensions mailbox
+			foreach ($vmcontexts as $vmcontext) {
+				if(isset($uservm[$vmcontext][$extnum])){
+					//$vmname = $uservm[$vmcontext][$extnum]['name'];
+					//$vmboxes[$extnum] = array($extnum, '"' . $vmname . '" <' . $extnum . '>');
+					$vmboxes[$extnum] = true;
+				}
+			}
+		}
+	}
+	
+	// return an associative array with destination and description
+	// core provides both users and voicemail boxes as destinations
+	if (isset($results)) {
+		foreach($results as $result) {
+			$extens[] = array('destination' => 'from-did-direct,'.$result['0'].',1', 'description' => ' <'.$result['0'].'> '.$result['1'], 'category' => 'Extensions');
+			if(isset($vmboxes[$result['0']])) {
+				$extens[] = array('destination' => 'ext-local,vmb'.$result['0'].',1', 'description' => '<'.$result[0].'> '.$result[1].' (busy)', 'category' => 'Voicemail');
+				$extens[] = array('destination' => 'ext-local,vmu'.$result['0'].',1', 'description' => '<'.$result[0].'> '.$result[1].' (unavail)', 'category' => 'Voicemail');
+				$extens[] = array('destination' => 'ext-local,vms'.$result['0'].',1', 'description' => '<'.$result[0].'> '.$result[1].' (no-msg)', 'category' => 'Voicemail');
+			}
+		}
+	}
+	
+	if (isset($extens))
+		return $extens;
+	else
+		return null;
+
+}
+
+/* 	Generates dialplan for "core" components (extensions & inbound routing)
+	We call this with retrieve_conf
+*/
+function core_get_config($engine) {
+	global $ext;  // is this the best way to pass this?
+	global $version;  // this is not the best way to pass this, this should be passetd together with $engine
+	global $amp_conf;
+
+	$modulename = "core";
+	
+	switch($engine) {
+		case "asterisk":
+			// FeatureCodes
+			$fcc = new featurecode($modulename, 'userlogon');
+			$fc_userlogon = $fcc->getCodeActive();
+			unset($fcc);
+
+			$fcc = new featurecode($modulename, 'userlogoff');
+			$fc_userlogoff = $fcc->getCodeActive();
+			unset($fcc);
+
+			$fcc = new featurecode($modulename, 'zapbarge');
+			$fc_zapbarge = $fcc->getCodeActive();
+			unset($fcc);
+
+			$fcc = new featurecode($modulename, 'chanspy');
+			$fc_chanspy = $fcc->getCodeActive();
+			unset($fcc);
+
+			$fcc = new featurecode($modulename, 'simu_pstn');
+			$fc_simu_pstn = $fcc->getCodeActive();
+			unset($fcc);
+
+			$fcc = new featurecode($modulename, 'simu_fax');
+			$fc_simu_fax = $fcc->getCodeActive();
+			unset($fcc);
+
+			$fcc = new featurecode($modulename, 'pickup');
+			$fc_pickup = $fcc->getCodeActive();
+			unset($fcc);
+
+			// Log on / off -- all in one context
+			if ($fc_userlogoff != '' || $fc_userlogon != '') {
+				$ext->addInclude('from-internal-additional', 'app-userlogonoff'); // Add the include from from-internal
+				
+				if ($fc_userlogoff != '') {
+					$ext->add('app-userlogonoff', $fc_userlogoff, '', new ext_macro('user-logoff'));
+					$ext->add('app-userlogonoff', $fc_userlogoff, '', new ext_hangup(''));
+				}
+	
+				if ($fc_userlogon != '') {
+					$ext->add('app-userlogonoff', $fc_userlogon, '', new ext_macro('user-logon'));
+					$ext->add('app-userlogonoff', $fc_userlogon, '', new ext_hangup(''));
+					
+					$clen = strlen($fc_userlogon);
+					$fc_userlogon = "_$fc_userlogon.";
+					$ext->add('app-userlogonoff', $fc_userlogon, '', new ext_macro('user-logon,${EXTEN:'.$clen.'}'));
+					$ext->add('app-userlogonoff', $fc_userlogon, '', new ext_hangup(''));
+				}
+			}
+
+			// Call pickup using app_pickup - Note that '**xtn' is hard-coded into the GXPs and SNOMs as a number to dial
+			// when a user pushes a flashing BLF. 
+			if ($fc_pickup != '') {
+				$ext->addInclude('from-internal-additional', 'app-pickup');
+				$fclen = strlen($fc_pickup);
+				$ext->add('app-pickup', "_$fc_pickup.", '', new ext_NoOp('Attempt to Pickup ${EXTEN:'.$fclen.'} by ${CALLERID(num)}'));
+				if (strstr($version, 'BRI')) 
+					$ext->add('app-pickup', "_$fc_pickup.", '', new ext_dpickup('${EXTEN:'.$fclen.'}'));
+				else
+					$ext->add('app-pickup', "_$fc_pickup.", '', new ext_pickup('${EXTEN:'.$fclen.'}'));
+			}
+			
+			
+			// zap barge
+			if ($fc_zapbarge != '') {
+				$ext->addInclude('from-internal-additional', 'app-zapbarge'); // Add the include from from-internal
+				
+				$ext->add('app-zapbarge', $fc_zapbarge, '', new ext_macro('user-callerid'));
+				$ext->add('app-zapbarge', $fc_zapbarge, '', new ext_setvar('GROUP()','${CALLERID(number)}'));
+				$ext->add('app-zapbarge', $fc_zapbarge, '', new ext_answer(''));
+				$ext->add('app-zapbarge', $fc_zapbarge, '', new ext_wait(1));
+				$ext->add('app-zapbarge', $fc_zapbarge, '', new ext_zapbarge(''));
+				$ext->add('app-zapbarge', $fc_zapbarge, '', new ext_hangup(''));
+			}
+
+			// chan spy
+			if ($fc_chanspy != '') {
+				$ext->addInclude('from-internal-additional', 'app-chanspy'); // Add the include from from-internal
+				$ext->add('app-chanspy', $fc_chanspy, '', new ext_macro('user-callerid'));
+				$ext->add('app-chanspy', $fc_chanspy, '', new ext_answer(''));
+				$ext->add('app-chanspy', $fc_chanspy, '', new ext_wait(1));
+				$ext->add('app-chanspy', $fc_chanspy, '', new ext_chanspy(''));
+				$ext->add('app-chanspy', $fc_chanspy, '', new ext_hangup(''));
+			}
+			
+			// Simulate options (ext-test)
+			if ($fc_simu_pstn != '' || $fc_simu_fax != '') {
+				$ext->addInclude('from-internal-additional', 'ext-test'); // Add the include from from-internal
+				
+				if ($fc_simu_pstn != '') {
+					$ext->add('ext-test', $fc_simu_pstn, '', new ext_goto('1', 's', 'from-pstn'));
+				}
+
+				if ($fc_simu_fax != '') {
+					$ext->add('ext-test', $fc_simu_fax, '', new ext_goto('1', 'in_fax', 'ext-fax'));
+				}
+
+				$ext->add('ext-test', 'h', '', new ext_macro('hangupcall'));
+			}
+			
+			/* Always have Fax detection in ext-did, no matter what */
+			$ext->add('ext-did', 'fax', '', new ext_goto('1','in_fax','ext-fax'));
+
+			/* inbound routing extensions */
+			$didlist = core_did_list();
+			if(is_array($didlist)){
+				$catchall = false;
+				$catchall_context='ext-did-catchall';
+				foreach($didlist as $item) {
+					$did = core_did_get($item['extension'],$item['cidnum'],$item['channel']);
+					$exten = $did['extension'];
+					$cidnum = $did['cidnum'];
+					$channel = $did['channel'];
+
+					$exten = (empty($exten)?"s":$exten);
+					$exten = $exten.(empty($cidnum)?"":"/".$cidnum); //if a CID num is defined, add it
+
+					if (empty($channel))
+						$context = "ext-did";
+					else {
+						$context = "macro-from-zaptel-{$channel}";
+						if (!isset($zapchan[$channel])) {
+							// create the macro-from-zaptel-$chan context and load up the
+							// startup settings
+							$ext->add($context, 'fax', '', new ext_goto('1','in_fax','ext-fax'));
+							$ext->add($context, 's', '', new ext_noop('Entering '.$context.' with DID = ${DID}'));
+							$zapchan[$channel] = "unfinished";
+						}
+					}
+
+					// Start inbound processing. Unneeded line to be possibly overridden by something in 
+					// extensions_custom.conf
+					$ext->add($context, $exten, '', new ext_setvar('__FROM_DID','${EXTEN}'));
+					// always set callerID name
+					$ext->add($context, $exten, '', new ext_gotoif('$[ "${CALLERID(name)}" != "" ] ','cidok'));
+					$ext->add($context, $exten, '', new ext_setvar('CALLERID(name)','${CALLERID(num)}'));
+					$ext->add($context, $exten, 'cidok', new ext_noop('CallerID is ${CALLERID(all)}'));
+
+					if (!empty($item['mohclass']) && trim($item['mohclass']) != 'default') {
+						$ext->add($context, $exten, '', new ext_setmusiconhold($item['mohclass']));
+						$ext->add($context, $exten, '', new ext_setvar('__MOHCLASS',$item['mohclass']));
+					}
+
+					// If we require RINGING, signal it as soon as we enter.
+					if ($item['ringing'] === "CHECKED") {
+						$ext->add($context, $exten, '', new ext_ringing(''));
+					}
+
+					if ($exten == "s" && $context == "ext-did") {  
+						//if the exten is s, then also make a catchall for undefined DIDs if it's not a zaptel route
+						$catchaccount = "_X.".(empty($cidnum)?"":"/".$cidnum);
+						if ($catchaccount == "_X.") 
+							$catchall = true;
+						$ext->add($catchall_context, $catchaccount, '', new ext_NoOp('Catch-All DID Match - Found ${EXTEN} - You probably want a DID for this.'));
+						$ext->add($catchall_context, $catchaccount, '', new ext_goto('1','s','ext-did'));
+					}
+					
+					if ($item['faxexten'] != "default") {
+						$ext->add($context, $exten, '', new ext_setvar('FAX_RX',$item['faxexten']));
+					}
+					if (!empty($item['faxemail'])) {
+						$ext->add($context, $exten, '', new ext_setvar('FAX_RX_EMAIL',$item['faxemail']));
+					}
+					if ($item['answer'] == "1") {
+						$ext->add($context, $exten, '', new ext_answer(''));
+						$ext->add($context, $exten, '', new ext_wait($item['wait']));
+					}
+					if ($item['answer'] == "2") { // NVFaxDetect
+						$ext->add($context, $exten, '', new ext_answer(''));
+						$ext->add($context, $exten, '', new ext_playtones('ring'));
+						$ext->add($context, $exten, '', new ext_nvfaxdetect($item['wait']));
+					}
+					if ($item['privacyman'] == "1") {
+						$ext->add($context, $exten, '', new ext_macro('privacy-mgr'));
+					}
+					if (!empty($item['alertinfo'])) {
+						$ext->add($context, $exten, '', new ext_setvar("__ALERT_INFO", str_replace(';', '\;', $item['alertinfo'])));
+					}
+					// Add CID prefix, no need to do checks for existing pre-pends, this is an incoming did so this should
+					// be the first time the CID is manipulated. We set _RGPREFIX which is the same used throughout the different
+					// modules.
+					//
+					// TODO: If/When RGPREFIX is added to trunks, then see code in ringgroups to strip prefix if added here.
+					//
+					// TODO: core FreePBX documentation about this standard. (and probably rename from RGPREFIX to CIDPREFIX)
+					//
+					if (!empty($item['grppre'])) {
+						$ext->add($context, $exten, '', new ext_setvar('_RGPREFIX', $item['grppre']));
+						$ext->add($context, $exten, '', new ext_setvar('CALLERID(name)','${RGPREFIX}${CALLERID(name)}'));
+					}
+					
+					// If we're doing a zaptel route, now we need to do the gotos ONLY IF it's the first time round.
+					// Except for the fact that this doesn't work. Not at all. Dial returns -1 and hangs up the 
+					// call. This is fixed in 1.4 with TryExec(), but until then, we can't match on zap
+					// _and_ anything else.  When we decide to say 'Only 1.4!' then we can reenable this
+					// and use TryExec(Goto..) and then check ${TRYSTATUS} for FAILED or SUCCESS. I didn't
+					// bother actually writing that, as the syntax may change.
+					//if (isset($zapchan[$channel]) && $zapchan[$channel] == "unfinished") {
+					//	$ext->add($context, 's', '', new ext_gotoif('$[ "${DID}" = "s" ]', 'nos', 'sok'));
+					//	$ext->add($context, 's', 'nos', new ext_noop('Skipping ${DID} because it is s'));
+					//	$ext->add($context, 's', '', new ext_goto("trycid"));
+					//	$ext->add($context, 's', 'sok', new ext_noop('Trying ${DID}'));
+					//	$ext->add($context, 's', '', new ext_goto("1", '${DID}'));
+					//	$ext->add($context, 's', 'trycid', new ext_gotoif('$[ "${CALLERID(num)}" = "" ]', 'nocid', 'cidok'));
+					//	$ext->add($context, 's', 'nocid', new ext_noop('Skipping empty CallerID Num'));
+					//	$ext->add($context, 's', '', new ext_goto("end"));
+					//	$ext->add($context, 's', 'cidok', new ext_noop('Trying ${DID}/${CALLERID(num)}'));
+					//	$ext->add($context, 's', '', new ext_goto("1", '${DID}/${CALLERID(num)}'));
+					//	$ext->add($context, 's', 'end', new ext_noop('End of macro init'));
+						// Now set $zapchan[$channel] so we don't do this again
+						$zapchan[$channel] = "set";
+					//}
+					//the goto destination
+					// destination field in 'incoming' database is backwards from what ext_goto expects
+					$goto_context = strtok($did['destination'],',');
+					$goto_exten = strtok(',');
+					$goto_pri = strtok(',');
+					$ext->add($context, $exten, '', new ext_goto($goto_pri,$goto_exten,$goto_context));
+					
+				}
+				// If there's not a catchall, make one with an error message
+				if (!$catchall) {
+					$ext->add($catchall_context, 's', '', new ext_noop("No DID or CID Match"));
+					$ext->add($catchall_context, 's', '', new ext_answer(''));
+					$ext->add($catchall_context, 's', '', new ext_wait('2'));
+					$ext->add($catchall_context, 's', '', new ext_playback('ss-noservice'));
+					$ext->add($catchall_context, 's', '', new ext_sayalpha('${FROM_DID}'));
+					$ext->add($catchall_context, '_[*#X].', '', new ext_setvar('__FROM_DID', '${EXTEN}'));
+					$ext->add($catchall_context, '_[*#X].', '', new ext_noop('Received an unknown call with DID set to ${EXTEN}'));
+					$ext->add($catchall_context, '_[*#X].', '', new ext_goto('1','s','ext-did'));
+				}
+					
+			}
+
+			/* MODIFIED (PL)
+			 *
+			 * Add Direct DIDs
+			 *
+			 * This functions creates a new context, ext-did-direct, used to route an incoming DID directly to the specified user.
+ 			 * The purpose is to use when a user has a personal external DID. This keeps it clean and easy to administer.
+ 			 * Any conflict with those routes will depend on which of the two contexts are included first in the extensions.conf file.
+ 			 *
+ 			 * Calls are sent to context from-did-direct though this feature. You must create that context in extenions.conf or
+ 			 * in extensions_custom.conf and it should look something like:
+ 			 *
+ 			 * [from-did-direct]
+ 			 * include => ext-findmefollow
+ 			 * include => ext-local
+ 			 *
+ 			 * This is so that personal ring groups are used if they exist for the direct did and if not, then the local extension.
+			 * If the module is not implented, it will just go to the users extension.
+ 			 */
+
+			$directdidlist = core_directdid_list();
+			if(is_array($directdidlist)){
+				$context = "ext-did";
+				if(!is_array($didlist)){
+					/* if not set above, add one here */
+					$ext->add($context, 'fax', '', new ext_goto('1','in_fax','ext-fax'));
+				}
+				foreach($directdidlist as $item) {
+					$exten = $item['directdid'];
+					$ext->add($context, $exten, '', new ext_setvar('__FROM_DID','${EXTEN}'));
+					// always set callerID name
+					$ext->add($context, $exten, '', new ext_gotoif('$[ "${CALLERID(name)}" != "" ] ','cidok'));
+					$ext->add($context, $exten, '', new ext_setvar('CALLERID(name)','${CALLERID(num)}'));
+					$ext->add($context, $exten, 'cidok', new ext_noop('CallerID is ${CALLERID(all)}'));
+
+					if (!empty($item['mohclass']) && trim($item['mohclass']) != 'default') {
+						$ext->add($context, $exten, '', new ext_setmusiconhold($item['mohclass']));
+						$ext->add($context, $exten, '', new ext_setvar('__MOHCLASS',$item['mohclass']));
+					}
+					
+					if ($item['faxexten'] != "default") {
+						$ext->add($context, $exten, '', new ext_setvar('FAX_RX',$item['faxexten']));
+					}
+					if (!empty($item['faxemail'])) {
+						$ext->add($context, $exten, '', new ext_setvar('FAX_RX_EMAIL',$item['faxemail']));
+					}
+					if ($item['answer'] == "1") {
+						$ext->add($context, $exten, '', new ext_answer(''));
+						$ext->add($context, $exten, '', new ext_wait($item['wait']));
+					}
+					if ($item['answer'] == "2") { // NVFaxDetect
+						$ext->add($context, $exten, '', new ext_answer(''));
+						$ext->add($context, $exten, '', new ext_playtones('ring'));
+						$ext->add($context, $exten, '', new ext_nvfaxdetect($item['wait']));
+					}
+					if ($item['privacyman'] == "1") {
+						$ext->add($context, $exten, '', new ext_macro('privacy-mgr'));
+					}
+
+
+					if (!empty($item['didalert'])) {
+						$ext->add($context, $exten, '', new ext_setvar("_ALERT_INFO", str_replace(';', '\;', $item['didalert'])));
+					}
+					$goto_context = 'from-did-direct';
+					$goto_exten = $item['extension'];
+					$goto_pri = 1;
+					$ext->add($context, $exten, '', new ext_goto($goto_pri,$goto_exten,$goto_context));
+
+				}
+			}
+
+			
+			/* user extensions */
+			$ext->addInclude('from-internal-additional','ext-local');
+			$userlist = core_users_list();
+			if (is_array($userlist)) {
+				foreach($userlist as $item) {
+					$exten = core_users_get($item[0]);
+					$vm = ((($exten['voicemail'] == "novm") || ($exten['voicemail'] == "disabled") || ($exten['voicemail'] == "")) ? "novm" : $exten['extension']);
+
+					if (isset($exten['ringtimer']) && $exten['ringtimer'] != 0)
+						$ext->add('ext-local', $exten['extension'], '', new ext_setvar('__RINGTIMER',$exten['ringtimer']));
+					
+					$ext->add('ext-local', $exten['extension'], '', new ext_macro('exten-vm',$vm.",".$exten['extension']));
+					$ext->add('ext-local', $exten['extension'], '', new ext_hangup(''));
+					
+					if($vm != "novm") {
+						$ext->add('ext-local', '${VM_PREFIX}'.$exten['extension'], '', new ext_macro('vm',"$vm,DIRECTDIAL"));
+						$ext->add('ext-local', '${VM_PREFIX}'.$exten['extension'], '', new ext_hangup(''));
+						$ext->add('ext-local', 'vmb'.$exten['extension'], '', new ext_macro('vm',"$vm,BUSY"));
+						$ext->add('ext-local', 'vmb'.$exten['extension'], '', new ext_hangup(''));
+						$ext->add('ext-local', 'vmu'.$exten['extension'], '', new ext_macro('vm',"$vm,NOANSWER"));
+						$ext->add('ext-local', 'vmu'.$exten['extension'], '', new ext_hangup(''));
+						$ext->add('ext-local', 'vms'.$exten['extension'], '', new ext_macro('vm',"$vm,NOMESSAGE"));
+						$ext->add('ext-local', 'vms'.$exten['extension'], '', new ext_hangup(''));
+					}
+						
+					$hint = core_hint_get($exten['extension']);
+					if (!empty($hint))
+						$ext->addHint('ext-local', $exten['extension'], $hint);
+					if ($exten['sipname']) {
+						$ext->add('ext-local', $exten['sipname'], '', new ext_goto('1',$item[0],'from-internal'));
+					}
+				}
+			}
+
+			// create from-trunk context for each trunk that adds counts to channels
+			//
+			$trunklist = core_trunks_list(true);
+			if (is_array($trunklist)) {
+				foreach ($trunklist as $trunkprops) {
+					if (trim($trunkprops['value']) == 'on') {
+						// value of on is disabled and for zap we don't create a context
+						continue;
+					}
+					switch ($trunkprops['tech']) {
+						case 'IAX':
+						case 'IAX2':
+						case 'SIP':
+							$trunkgroup = $trunkprops['globalvar'];
+							$trunkcontext  = "from-trunk-".$trunkprops['name'];
+							$ext->add($trunkcontext, '_.', '', new ext_setvar('GROUP()',$trunkgroup));
+							$ext->add($trunkcontext, '_.', '', new ext_goto('1','${EXTEN}','from-trunk'));
+							break;
+						default:
+					}
+				}
+			}
+
+			/* dialplan globals */
+			// modules should NOT use the globals table to store anything!
+			// modules should use $ext->addGlobal("testvar","testval"); in their module_get_config() function instead
+			// I'm cheating for core functionality - do as I say, not as I do ;-)		
+
+			// Auto add these globals to give access to agi scripts and other needs, unless defined in the global table.
+			//
+			$amp_conf_globals = array( 
+				"ASTETCDIR", 
+				"ASTMODDIR", 
+				"ASTVARLIBDIR", 
+				"ASTAGIDIR", 
+				"ASTSPOOLDIR", 
+				"ASTRUNDIR", 
+				"ASTLOGDIR",
+				"CWINUSEBUSY",
+				"AMPMGRUSER",
+				"AMPMGRPASS"
+			);
+
+			$sql = "SELECT * FROM globals";
+			$globals = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
+			foreach($globals as $global) {
+				$ext->addGlobal($global['variable'],$global['value']);
+
+				// now if for some reason we have a variable in the global table
+				// that is in our $amp_conf_globals list, then remove it so we
+				// don't duplicate, the sql table will take precedence
+				//
+				if (array_key_exists($global['variable'],$amp_conf_globals)) {
+					$rm_keys = array_keys($amp_conf_globals,$global['variable']);
+					foreach ($rm_keys as $index) {
+						unset($amp_conf_globals[$index]);
+					}
+				}
+			}
+			foreach ($amp_conf_globals as $global) {
+				if (isset($amp_conf[$global])) {
+					$value = $amp_conf[$global];
+					if ($value === true || $value === false) {
+						$value = ($value) ? 'true':'false';
+					}
+					$ext->addGlobal($global, $value);
+					out("Added to globals: $global = $value");
+				}
+			}
+			
+			/* outbound routes */
+			// modules should use their own table for storage (and module_get_config() to add dialplan)
+			// modules should NOT use the extension table to store anything!
+			$sql = "SELECT application FROM extensions where context = 'outbound-allroutes' ORDER BY application";
+			$outrts = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
+			$ext->addInclude('from-internal-additional','outbound-allroutes');
+			$ext->add('outbound-allroutes', 'foo', '', new ext_noop('bar'));
+			foreach($outrts as $outrt) {
+				$ext->addInclude('outbound-allroutes',$outrt['application']);
+				$sql = "SELECT * FROM extensions where context = '".$outrt['application']."' ORDER BY extension, CAST(priority AS UNSIGNED) ASC";
+				$thisrt = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
+				foreach($thisrt as $exten) {
+					//if emergencyroute, then set channel var
+					if(strpos($exten['args'],"EMERGENCYROUTE") !== false)
+						$ext->add($outrt['application'], $exten['extension'], '', new ext_setvar("EMERGENCYROUTE",substr($exten['args'],15)));
+					if(strpos($exten['args'],"INTRACOMPANYROUTE") !== false)
+						$ext->add($outrt['application'], $exten['extension'], '', new ext_setvar("INTRACOMPANYROUTE",substr($exten['args'],18)));
+					// Don't set MOHCLASS if already set, threre may be a feature code that overrode it
+					if(strpos($exten['args'],"MOHCLASS") !== false)
+						$ext->add($outrt['application'], $exten['extension'], '', new ext_setvar("MOHCLASS", '${IF($["x${MOHCLASS}"="x"]?'.substr($exten['args'],9).':${MOHCLASS})}' ));
+					if(strpos($exten['args'],"dialout-trunk") !== false)
+						$ext->add($outrt['application'], $exten['extension'], '', new ext_macro($exten['args']));
+					if(strpos($exten['args'],"dialout-enum") !== false)
+						$ext->add($outrt['application'], $exten['extension'], '', new ext_macro($exten['args']));
+					if(strpos($exten['args'],"outisbusy") !== false)
+						$ext->add($outrt['application'], $exten['extension'], '', new ext_macro("outisbusy"));
+				}
+			}
+			general_generate_indications();
+
+			// "blackhole" destinations
+			$ext->add('app-blackhole', 'hangup', '', new ext_noop('Blackhole Dest: Hangup'));
+			$ext->add('app-blackhole', 'hangup', '', new ext_hangup());
+
+			$ext->add('app-blackhole', 'zapateller', '', new ext_noop('Blackhole Dest: Play SIT Tone'));
+			$ext->add('app-blackhole', 'zapateller', '', new ext_answer());
+			$ext->add('app-blackhole', 'zapateller', '', new ext_zapateller());
+			// Should hangup ?
+			// $ext->add('app-blackhole', 'zapateller', '', new ext_hangup());
+					
+			$ext->add('app-blackhole', 'musiconhold', '', new ext_noop('Blackhole Dest: Put caller on hold forever'));
+			$ext->add('app-blackhole', 'musiconhold', '', new ext_answer());
+			$ext->add('app-blackhole', 'musiconhold', '', new ext_musiconhold());
+
+			$ext->add('app-blackhole', 'congestion', '', new ext_noop('Blackhole Dest: Congestion'));
+			$ext->add('app-blackhole', 'congestion', '', new ext_answer());
+			$ext->add('app-blackhole', 'congestion', '', new ext_playtones('congestion'));
+			$ext->add('app-blackhole', 'congestion', '', new ext_congestion());
+			$ext->add('app-blackhole', 'congestion', '', new ext_hangup());
+
+			$ext->add('app-blackhole', 'busy', '', new ext_noop('Blackhole Dest: Busy'));
+			$ext->add('app-blackhole', 'busy', '', new ext_answer());
+			$ext->add('app-blackhole', 'busy', '', new ext_playtones('busy'));
+			$ext->add('app-blackhole', 'busy', '', new ext_busy());
+			$ext->add('app-blackhole', 'busy', '', new ext_hangup());
+
+			if ($amp_conf['AMPBADNUMBER'] !== false) {
+				$context = 'bad-number';
+				$exten = '_X.';
+				$ext->add($context, $exten, '', new extension('ResetCDR()'));
+				$ext->add($context, $exten, '', new extension('NoCDR()'));
+				$ext->add($context, $exten, '', new ext_wait('1'));
+				$ext->add($context, $exten, '', new ext_playback('silence/1&cannot-complete-as-dialed&check-number-dial-again,noanswer'));
+				$ext->add($context, $exten, '', new ext_wait('1'));
+				$ext->add($context, $exten, '', new ext_congestion('20'));
+				$ext->add($context, $exten, '', new ext_hangup());
+
+				$exten = '_*.';
+				$ext->add($context, $exten, '', new extension('ResetCDR()'));
+				$ext->add($context, $exten, '', new extension('NoCDR()'));
+				$ext->add($context, $exten, '', new ext_wait('1'));
+				$ext->add($context, $exten, '', new ext_playback('silence/1&feature-not-avail-line&silence/1&cannot-complete-as-dialed&check-number-dial-again,noanswer'));
+				$ext->add($context, $exten, '', new ext_wait('1'));
+				$ext->add($context, $exten, '', new ext_congestion('20'));
+				$ext->add($context, $exten, '', new ext_hangup());
+			}
+
+		break;
+	}
+}
+
+
+
+
+
+
+
+
+
+
+
+/* begin page.ampusers.php functions */
+
+function core_ampusers_add($username, $password, $extension_low, $extension_high, $deptname, $sections) {
+	$sql = "INSERT INTO ampusers (username, password, extension_low, extension_high, deptname, sections) VALUES (";
+	$sql .= "'".$username."',";
+	$sql .= "'".$password."',";
+	$sql .= "'".$extension_low."',";
+	$sql .= "'".$extension_high."',";
+	$sql .= "'".$deptname."',";
+	$sql .= "'".implode(";",$sections)."');";
+	
+	sql($sql,"query");
+}
+
+function core_ampusers_del($username) {
+	$sql = "DELETE FROM ampusers WHERE username = '".$username."'";
+	sql($sql,"query");
+}
+
+function core_ampusers_list() {
+	$sql = "SELECT username FROM ampusers ORDER BY username";
+	return sql($sql,"getAll");
+}
+
+/* end page.ampusers.php functions */
+
+
+
+
+
+
+
+
+
+/* begin page.did.php functions */
+
+function core_did_list($order='extension'){
+	switch ($order) {
+		case 'description':
+			$sql = "SELECT * FROM incoming ORDER BY description,extension,cidnum";
+			break;
+		case 'extension':
+		default:
+			$sql = "SELECT * FROM incoming ORDER BY extension,cidnum";
+	}
+	return sql($sql,"getAll",DB_FETCHMODE_ASSOC);
+}
+
+function core_did_get($extension="",$cidnum="",$channel=""){
+	$sql = "SELECT * FROM incoming WHERE cidnum = \"$cidnum\" AND extension = \"$extension\" AND channel = \"$channel\"";
+	return sql($sql,"getRow",DB_FETCHMODE_ASSOC);
+}
+
+function core_did_del($extension,$cidnum, $channel){
+	$sql="DELETE FROM incoming WHERE cidnum = \"$cidnum\" AND extension = \"$extension\" AND channel = \"$channel\"";
+	sql($sql);
+}
+
+function core_did_edit($old_extension,$old_cidnum, $old_channel, $incoming){
+
+	$old_extension = addslashes(trim($old_extension));
+	$old_cidnum = addslashes(trim($old_cidnum));
+	$old_channel = addslashes(trim($old_channel));
+
+	$incoming['extension'] = trim($incoming['extension']);
+	$incoming['cidnum'] = trim($incoming['cidnum']);
+	$incoming['channel'] = trim($incoming['channel']);
+
+	$extension = addslashes($incoming['extension']);
+	$cidnum = addslashes($incoming['cidnum']);
+	$channel = addslashes($incoming['channel']);
+
+	// if did or cid changed, then check to make sure that this pair is not already being used.
+	//
+	if (($extension != $old_extension) || ($cidnum != $old_cidnum)) {
+		$existing=core_did_get($extension,$cidnum,$channel);
+		if (empty($existing) && (trim($cidnum) == "")) {
+			$existing_directdid = core_users_directdid_get($extension);
+		} else {
+			$existing_directdid = "";
+		}
+	} else {
+		$existing = $existing_directdid = "";
+	}
+
+	if (empty($existing) && empty($existing_directdid)) {
+		core_did_del($old_extension,$old_cidnum,$old_channel);
+		core_did_add($incoming);
+		return true;
+	} else {
+		if (!empty($existing)) {
+			echo "<script>javascript:alert('"._("A route for this DID/CID already exists!")." => ".$existing['extension']."/".$existing['cidnum']."')</script>";
+		} else {
+			echo "<script>javascript:alert('"._("A directdid for this DID is already associated with extension:")." ".$existing_directdid['extension']." (".$existing_directdid['name'].")')</script>";
+		}
+		return false;
+	}
+}
+
+function core_did_add($incoming){
+	foreach ($incoming as $key => $val) { ${$key} = addslashes($val); } // create variables from request
+
+	// Check to make sure the did is not being used elsewhere
+	//
+	$existing=core_did_get($extension,$cidnum,$channel);
+	if (empty($existing) && (trim($cidnum) == "")) {
+		$existing_directdid = core_users_directdid_get($extension);
+	} else {
+		$existing_directdid = "";
+	}
+
+	if (empty($existing) && empty($existing_directdid)) {
+		$destination=${$goto0.'0'};
+		$sql="INSERT INTO incoming (cidnum,extension,destination,faxexten,faxemail,answer,wait,privacyman,alertinfo, channel, ringing, mohclass, description, grppre) values ('$cidnum','$extension','$destination','$faxexten','$faxemail','$answer','$wait','$privacyman','$alertinfo', '$channel', '$ringing', '$mohclass', '$description', '$grppre')";
+		sql($sql);
+		return true;
+	} else {
+		if (!empty($existing)) {
+			echo "<script>javascript:alert('"._("A route for this DID/CID already exists!")." => ".$existing['extension']."/".$existing['cidnum']."')</script>";
+		} else {
+			echo "<script>javascript:alert('"._("A directdid for this DID is already associated with extension:")." ".$existing_directdid['extension']." (".$existing_directdid['name'].")')</script>";
+		}
+		return false;
+	}
+}
+
+/* end page.did.php functions */
+
+
+
+
+
+
+
+/* begin page.devices.php functions */
+
+//get the existing devices
+function core_devices_list($tech="all") {
+	$sql = "SELECT id,description FROM devices";
+	switch (strtoupper($tech)) {
+		case "IAX":
+			$sql .= " WHERE tech = 'iax2'";
+			break;
+		case "IAX2":
+		case "SIP":
+		case "ZAP":
+			$sql .= " WHERE tech = '".strtolower($tech)."'";
+			break;
+		case "ALL":
+		default:
+	}
+	$sql .= ' ORDER BY id';
+	$results = sql($sql,"getAll");
+
+	foreach($results as $result){
+		if (checkRange($result[0])){
+			$extens[] = array(
+				0=>$result[0],  // for backwards compatibility
+				1=>$result[1],
+				'id'=>$result[0], // FETCHMODE_ASSOC emulation
+				'description'=>$result[1],
+			);
+		}
+	}
+	if (isset($extens)) {
+		return $extens;
+	} else { 
+		return null;
+	}
+}
+
+
+function core_devices_add($id,$tech,$dial,$devicetype,$user,$description,$emergency_cid=null,$editmode=false){
+	global $amp_conf;
+	global $currentFile;
+	global $astman;
+
+	$display = isset($_REQUEST['display'])?$_REQUEST['display']:'';
+
+	if (trim($id) == '' ) {
+		if ($display != 'extensions') {
+			echo "<script>javascript:alert('"._("You must put in a device id")."');</script>";
+		}
+		return false;
+	}
+	
+	//ensure this id is not already in use
+	$devices = core_devices_list();
+	if (is_array($devices)) {
+		foreach($devices as $device) {
+			if ($device[0] === $id) {
+				if ($display <> 'extensions') echo "<script>javascript:alert('"._("This device id is already in use")."');</script>";
+				return false;
+			}
+		}
+	}
+	//unless defined, $dial is TECH/id
+	if ( $dial == '' ) {
+		//zap is an exception
+		if ( strtolower($tech) == "zap" ) {
+			$zapchan = $_REQUEST['devinfo_channel'] != '' ? $_REQUEST['devinfo_channel'] : $_REQUEST['channel'];
+			$dial = 'ZAP/'.$zapchan;
+		} else {
+			$dial = strtoupper($tech)."/".$id;
+		}
+	}
+	
+	//check to see if we are requesting a new user
+	if ($user == "new") {
+		$user = $id;
+		$jump = true;
+	}
+	
+	if(!get_magic_quotes_gpc()) {
+		if(!empty($emergency_cid))
+			$emergency_cid = addslashes($emergency_cid);
+		if(!empty($description))
+			$description = addslashes($description);
+	}
+	
+	//insert into devices table
+	$sql="INSERT INTO devices (id,tech,dial,devicetype,user,description,emergency_cid) values (\"$id\",\"$tech\",\"$dial\",\"$devicetype\",\"$user\",\"$description\",\"$emergency_cid\")";
+	sql($sql);
+	
+	//add details to astdb
+	if ($astman) {
+		// if adding or editting a fixed device, user property should always be set
+		if ($devicetype == 'fixed' || !$editmode) {
+			$astman->database_put("DEVICE",$id."/user",$user);
+		}
+		// If changing from a fixed to an adhoc, the user property should be intialized
+		// to the new default, not remain as the previous fixed user
+		if ($editmode) {
+			$previous_type = $astman->database_get("DEVICE",$id."/type");
+			if ($previous_type == 'fixed' && $devicetype == 'adhoc') {
+				$astman->database_put("DEVICE",$id."/user",$user);
+			}
+		}
+		$astman->database_put("DEVICE",$id."/dial",$dial);
+		$astman->database_put("DEVICE",$id."/type",$devicetype);
+		$astman->database_put("DEVICE",$id."/default_user",$user);
+		if(!empty($emergency_cid)) {
+			$astman->database_put("DEVICE",$id."/emergency_cid","\"".$emergency_cid."\"");
+		}
+
+		if ($user != "none") {
+			$existingdevices = $astman->database_get("AMPUSER",$user."/device");
+			if (empty($existingdevices)) {
+				$astman->database_put("AMPUSER",$user."/device",$id);
+			} else {
+				$existingdevices_array = explode('&',$existingdevices);
+				if (!in_array($id, $existingdevices_array)) {
+					$existingdevices_array[]=$id;
+					$existingdevices = implode('&',$existingdevices_array);
+					$astman->database_put("AMPUSER",$user."/device",$existingdevices);
+				}
+			}
+		}
+
+	} else {
+		fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
+	}
+	
+	// create a voicemail symlink if needed
+	$thisUser = core_users_get($user);
+	if(isset($thisUser['voicemail']) && ($thisUser['voicemail'] != "novm")) {
+		if(empty($thisUser['voicemail']))
+			$vmcontext = "default";
+		else 
+			$vmcontext = $thisUser['voicemail'];
+		
+		//voicemail symlink
+		exec("rm -f /var/spool/asterisk/voicemail/device/".$id);
+		exec("/bin/ln -s /var/spool/asterisk/voicemail/".$vmcontext."/".$user."/ /var/spool/asterisk/voicemail/device/".$id);
+	}
+		
+	//take care of sip/iax/zap config
+	$funct = "core_devices_add".strtolower($tech);
+	if(function_exists($funct)){
+		$funct($id);
+	}
+	
+/*	if($user != "none") {
+		core_hint_add($user);
+	}*/
+	
+	//if we are requesting a new user, let's jump to users.php
+	if (isset($jump)) {
+		echo("<script language=\"JavaScript\">window.location=\"config.php?display=users&extdisplay={$id}&name={$description}\";</script>");
+	}
+	return true;
+}
+
+function core_devices_del($account,$editmode=false){
+	global $amp_conf;
+	global $currentFile;
+	global $astman;
+	
+	//get all info about device
+	$devinfo = core_devices_get($account);
+	
+	//delete details to astdb
+	if ($astman) {
+		// If a user was selected, remove this device from the user
+		$deviceuser = $astman->database_get("DEVICE",$account."/user");
+		if (isset($deviceuser) && $deviceuser != "none") {
+			// Remove the device record from the user's device list
+			$userdevices = $astman->database_get("AMPUSER",$deviceuser."/device");
+
+			// We need to remove just this user and leave the rest alone
+			$userdevicesarr = explode("&", $userdevices);
+			$userdevicesarr_hash = array_flip($userdevicesarr);
+			unset($userdevicesarr_hash[$account]);
+			$userdevicesarr = array_flip($userdevicesarr_hash);
+			$userdevices = implode("&", $userdevicesarr);
+			
+			if (empty($userdevices)) {
+					$astman->database_del("AMPUSER",$deviceuser."/device");
+			} else {
+					$astman->database_put("AMPUSER",$deviceuser."/device",$userdevices);
+			}
+		}
+		if (! $editmode) {
+			$astman->database_del("DEVICE",$account."/dial");
+			$astman->database_del("DEVICE",$account."/type");
+			$astman->database_del("DEVICE",$account."/user");
+			$astman->database_del("DEVICE",$account."/default_user");
+			$astman->database_del("DEVICE",$account."/emergency_cid");
+		}
+
+		//delete from devices table
+		$sql="DELETE FROM devices WHERE id = \"$account\"";
+		sql($sql);
+
+		//voicemail symlink
+		exec("rm -f /var/spool/asterisk/voicemail/device/".$account);
+	} else {
+		fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
+	}
+	
+	//take care of sip/iax/zap config
+	$funct = "core_devices_del".strtolower($devinfo['tech']);
+	if(function_exists($funct)){
+		$funct($account);
+	}
+}
+
+function core_devices_get($account){
+	//get all the variables for the meetme
+	$sql = "SELECT * FROM devices WHERE id = '$account'";
+	$results = sql($sql,"getRow",DB_FETCHMODE_ASSOC);
+	
+	//take care of sip/iax/zap config
+	$funct = "core_devices_get".strtolower($results['tech']);
+	if (!empty($results['tech']) && function_exists($funct)) {
+		$devtech = $funct($account);
+		if (is_array($devtech)){
+			$results = array_merge($results,$devtech);
+		}
+	}
+	
+	return $results;
+}
+
+// this function rebuilds the astdb based on device table contents
+// used on devices.php if action=resetall
+function core_devices2astdb(){
+	global $astman;
+	global $amp_conf;
+
+	$sql = "SELECT * FROM devices";
+	$devresults = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
+
+	//add details to astdb
+	if ($astman) {
+		$astman->database_deltree("DEVICE");
+		foreach ($devresults as $dev) {
+			extract($dev);	
+			$astman->database_put("DEVICE",$id."/dial",$dial);
+			$astman->database_put("DEVICE",$id."/type",$devicetype);
+			$astman->database_put("DEVICE",$id."/user",$user);		
+			// If a user is selected, add this device to the user
+			if ($user != "none") {
+					$existingdevices = $astman->database_get("AMPUSER",$user."/device");
+					if (!empty($existingdevices)) {
+							$existingdevices .= "&";
+					}
+					$astman->database_put("AMPUSER",$user."/device",$existingdevices.$id);
+			}
+			
+			// create a voicemail symlink if needed
+			$thisUser = core_users_get($user);
+			if(isset($thisUser['voicemail']) && ($thisUser['voicemail'] != "novm")) {
+				if(empty($thisUser['voicemail']))
+					$vmcontext = "default";
+				else 
+					$vmcontext = $thisUser['voicemail'];
+				//voicemail symlink
+				exec("rm -f /var/spool/asterisk/voicemail/device/".$id);
+				exec("/bin/ln -s /var/spool/asterisk/voicemail/".$vmcontext."/".$user."/ /var/spool/asterisk/voicemail/device/".$id);
+			}
+		}
+		return true;
+	} else {
+		return false;
+	}
+}
+
+// this function rebuilds the astdb based on users table contents
+// used on devices.php if action=resetall
+function core_users2astdb(){
+	global $amp_conf;
+	global $astman;
+
+	$sql = "SELECT * FROM users";
+	$userresults = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
+	
+	//add details to astdb
+	if ($astman) {
+		foreach($userresults as $usr) {
+			extract($usr);
+			$astman->database_put("AMPUSER",$extension."/password",$password);
+			$astman->database_put("AMPUSER",$extension."/ringtimer",$ringtimer);
+			$astman->database_put("AMPUSER",$extension."/noanswer",$noanswer);
+			$astman->database_put("AMPUSER",$extension."/recording",$recording);
+			$astman->database_put("AMPUSER",$extension."/outboundcid","\"".addslashes($outboundcid)."\"");
+			$astman->database_put("AMPUSER",$extension."/cidname","\"".addslashes($name)."\"");
+			$astman->database_put("AMPUSER",$extension."/voicemail","\"".$voicemail."\"");
+		}	
+		return true;
+	} else {
+		return false;
+	}
+
+//	TODO: this was...	
+// 	return $astman->disconnect();
+//	is "true" the correct value...?
+}
+
+//add to sip table
+function core_devices_addsip($account) {
+	global $db;
+	global $currentFile;
+
+	foreach ($_REQUEST as $req=>$data) {
+		if ( substr($req, 0, 8) == 'devinfo_' ) {
+			$keyword = substr($req, 8);
+			if ( $keyword == 'dial' && $data == '' ) {
+				$sipfields[] = array($account, $keyword, 'SIP/'.$account);
+			} elseif ($keyword == 'mailbox' && $data == '') {
+				$sipfields[] = array($account,'mailbox',$account.'@device');
+			} else {
+				$sipfields[] = array($account, $keyword, $data);
+			}
+		}
+	}
+	
+	if ( !is_array($sipfields) ) { // left for compatibilty....lord knows why !
+		$sipfields = array(
+			//array($account,'account',$account),
+			array($account,'accountcode',(isset($_REQUEST['accountcode']))?$_REQUEST['accountcode']:''),
+			array($account,'secret',(isset($_REQUEST['secret']))?$_REQUEST['secret']:''),
+			array($account,'canreinvite',(isset($_REQUEST['canreinvite']))?$_REQUEST['canreinvite']:'no'),
+			array($account,'context',(isset($_REQUEST['context']))?$_REQUEST['context']:'from-internal'),
+			array($account,'dtmfmode',(isset($_REQUEST['dtmfmode']))?$_REQUEST['dtmfmode']:''),
+			array($account,'host',(isset($_REQUEST['host']))?$_REQUEST['host']:'dynamic'),
+			array($account,'type',(isset($_REQUEST['type']))?$_REQUEST['type']:'friend'),
+			array($account,'mailbox',(isset($_REQUEST['mailbox']) && !empty($_REQUEST['mailbox']))?$_REQUEST['mailbox']:$account.'@device'),
+			array($account,'username',(isset($_REQUEST['username']))?$_REQUEST['username']:$account),
+			array($account,'nat',(isset($_REQUEST['nat']))?$_REQUEST['nat']:'yes'),
+			array($account,'port',(isset($_REQUEST['port']))?$_REQUEST['port']:'5060'),
+			array($account,'qualify',(isset($_REQUEST['qualify']))?$_REQUEST['qualify']:'yes'),
+			array($account,'callgroup',(isset($_REQUEST['callgroup']))?$_REQUEST['callgroup']:''),
+			array($account,'pickupgroup',(isset($_REQUEST['pickupgroup']))?$_REQUEST['pickupgroup']:''),
+			array($account,'disallow',(isset($_REQUEST['disallow']))?$_REQUEST['disallow']:''),
+			array($account,'allow',(isset($_REQUEST['allow']))?$_REQUEST['allow']:'')
+			//array($account,'record_in',(isset($_REQUEST['record_in']))?$_REQUEST['record_in']:'On-Demand'),
+			//array($account,'record_out',(isset($_REQUEST['record_out']))?$_REQUEST['record_out']:'On-Demand'),
+			//array($account,'callerid',(isset($_REQUEST['description']))?$_REQUEST['description']." <".$account.'>':'device'." <".$account.'>')
+		);
+	}
+
+	// Very bad
+	$sipfields[] = array($account,'account',$account);	
+	$sipfields[] = array($account,'callerid',(isset($_REQUEST['description']) && $_REQUEST['description'])?$_REQUEST['description']." <".$account.'>':'device'." <".$account.'>');
+	
+	// Where is this in the interface ??????
+	$sipfields[] = array($account,'record_in',($_REQUEST['record_in'])?$_REQUEST['record_in']:'On-Demand');
+	$sipfields[] = array($account,'record_out',($_REQUEST['record_out'])?$_REQUEST['record_out']:'On-Demand');
+
+	$compiled = $db->prepare('INSERT INTO sip (id, keyword, data) values (?,?,?)');
+	$result = $db->executeMultiple($compiled,$sipfields);
+	if(DB::IsError($result)) {
+		die_freepbx($result->getDebugInfo()."<br><br>".'error adding to SIP table');	
+	}
+}
+
+function core_devices_delsip($account) {
+	global $db;
+	global $currentFile;
+	
+	$sql = "DELETE FROM sip WHERE id = '$account'";
+	$result = $db->query($sql);
+	
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage().$sql);
+	}
+}
+
+function core_devices_getsip($account) {
+	global $db;
+	$sql = "SELECT keyword,data FROM sip WHERE id = '$account'";
+	$results = $db->getAssoc($sql);
+	if(DB::IsError($results)) {
+		$results = null;
+	}
+	
+	return $results;
+}
+
+//add to iax table
+function core_devices_addiax2($account) {
+	global $db;
+	global $currentFile;
+	
+	foreach ($_REQUEST as $req=>$data) {
+		if ( substr($req, 0, 8) == 'devinfo_' ) {
+			$keyword = substr($req, 8);
+			if ( $keyword == 'dial' && $data == '' ) {
+				$iaxfields[] = array($account, $keyword, 'IAX2/'.$account);
+			} elseif ($keyword == 'mailbox' && $data == '') {
+				$iaxfields[] = array($account,'mailbox',$account.'@device');
+			} else {
+				$iaxfields[] = array($account, $keyword, $data);
+			}
+		}
+	}
+	
+	if ( !is_array($iaxfields) ) { // left for compatibilty....lord knows why !
+		$iaxfields = array(
+			//array($account,'account',$account),
+			array($account,'secret',($_REQUEST['secret'])?$_REQUEST['secret']:''),
+			array($account,'notransfer',($_REQUEST['notransfer'])?$_REQUEST['notransfer']:'yes'),
+			array($account,'context',($_REQUEST['context'])?$_REQUEST['context']:'from-internal'),
+			array($account,'host',($_REQUEST['host'])?$_REQUEST['host']:'dynamic'),
+			array($account,'type',($_REQUEST['type'])?$_REQUEST['type']:'friend'),
+			array($account,'mailbox',($_REQUEST['mailbox'])?$_REQUEST['mailbox']:$account.'@device'),
+			array($account,'username',($_REQUEST['username'])?$_REQUEST['username']:$account),
+			array($account,'port',($_REQUEST['port'])?$_REQUEST['port']:'4569'),
+			array($account,'qualify',($_REQUEST['qualify'])?$_REQUEST['qualify']:'yes'),
+			array($account,'disallow',($_REQUEST['disallow'])?$_REQUEST['disallow']:''),
+			array($account,'allow',($_REQUEST['allow'])?$_REQUEST['allow']:''),
+			array($account,'accountcode',($_REQUEST['accountcode'])?$_REQUEST['accountcode']:'')
+			//array($account,'record_in',($_REQUEST['record_in'])?$_REQUEST['record_in']:'On-Demand'),
+			//array($account,'record_out',($_REQUEST['record_out'])?$_REQUEST['record_out']:'On-Demand'),
+			//array($account,'callerid',($_REQUEST['description'])?$_REQUEST['description']." <".$account.'>':'device'." <".$account.'>')
+		);
+	}
+
+	// Very bad
+	$iaxfields[] = array($account,'account',$account);	
+	$iaxfields[] = array($account,'callerid',(isset($_REQUEST['description']) && $_REQUEST['description'] != '')?$_REQUEST['description']." <".$account.'>':'device'." <".$account.'>');
+	// Asterisk treats no caller ID from an IAX device as 'hide callerid', and ignores the caller ID
+	// set in iax.conf. As we rely on this for pretty much everything, we need to specify the 
+	// callerid as a variable which gets picked up in macro-callerid.
+	// Ref - http://bugs.digium.com/view.php?id=456
+	$iaxfields[] = array($account,'setvar',"REALCALLERIDNUM=$account");
+	
+	// Where is this in the interface ??????
+	$iaxfields[] = array($account,'record_in',($_REQUEST['record_in'])?$_REQUEST['record_in']:'On-Demand');
+	$iaxfields[] = array($account,'record_out',($_REQUEST['record_out'])?$_REQUEST['record_out']:'On-Demand');
+	
+	$compiled = $db->prepare('INSERT INTO iax (id, keyword, data) values (?,?,?)');
+	$result = $db->executeMultiple($compiled,$iaxfields);
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage()."<br><br>error adding to IAX table");	
+	}
+}
+
+function core_devices_deliax2($account) {
+	global $db;
+	global $currentFile;
+	
+	$sql = "DELETE FROM iax WHERE id = '$account'";
+	$result = $db->query($sql);
+	
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage().$sql);
+	}
+}
+
+function core_devices_getiax2($account) {
+	global $db;
+	$sql = "SELECT keyword,data FROM iax WHERE id = '$account'";
+	$results = $db->getAssoc($sql);
+	if(DB::IsError($results)) {
+		$results = null;
+	}
+	
+	return $results;
+}
+
+function core_devices_addzap($account) {
+	global $db;
+	global $currentFile;
+	
+	foreach ($_REQUEST as $req=>$data) {
+		if ( substr($req, 0, 8) == 'devinfo_' ) {
+			$keyword = substr($req, 8);
+			if ( $keyword == 'dial' && $data == '' ) {
+				$zapchan = $_REQUEST['devinfo_channel'] != '' ? $_REQUEST['devinfo_channel'] : $_REQUEST['channel'];
+				$zapfields[] = array($account, $keyword, 'ZAP/'.$zapchan);
+			} elseif ($keyword == 'mailbox' && $data == '') {
+				$zapfields[] = array($account,'mailbox',$account.'@device');
+			} else {
+				$zapfields[] = array($account, $keyword, $data);
+			}
+		}
+	}
+	
+	if ( !is_array($zapfields) ) { // left for compatibilty....lord knows why !
+		$zapfields = array(
+			//array($account,'account',$account),
+			array($account,'context',($_REQUEST['context'])?$_REQUEST['context']:'from-internal'),
+			array($account,'mailbox',($_REQUEST['mailbox'])?$_REQUEST['mailbox']:$account.'@device'),
+			//array($account,'callerid',($_REQUEST['description'])?$_REQUEST['description']." <".$account.'>':'device'." <".$account.'>'),
+			array($account,'immediate',($_REQUEST['immediate'])?$_REQUEST['immediate']:'no'),
+			array($account,'signalling',($_REQUEST['signalling'])?$_REQUEST['signalling']:'fxo_ks'),
+			array($account,'echocancel',($_REQUEST['echocancel'])?$_REQUEST['echocancel']:'yes'),
+			array($account,'echocancelwhenbridged',($_REQUEST['echocancelwhenbridged'])?$_REQUEST['echocancelwhenbridged']:'no'),
+			array($account,'immediate',($_REQUEST['immediate'])?$_REQUEST['immediate']:'no'),	
+			array($account,'echotraining',($_REQUEST['echotraining'])?$_REQUEST['echotraining']:'800'),
+			array($account,'busydetect',($_REQUEST['busydetect'])?$_REQUEST['busydetect']:'no'),
+			array($account,'busycount',($_REQUEST['busycount'])?$_REQUEST['busycount']:'7'),
+			array($account,'callprogress',($_REQUEST['callprogress'])?$_REQUEST['callprogress']:'no'),
+			//array($account,'record_in',($_REQUEST['record_in'])?$_REQUEST['record_in']:'On-Demand'),	
+			//array($account,'record_out',($_REQUEST['record_out'])?$_REQUEST['record_out']:'On-Demand'),
+			array($account,'accountcode',(isset($_REQUEST['accountcode']))?$_REQUEST['accountcode']:''),
+			array($account,'channel',($_REQUEST['channel'])?$_REQUEST['channel']:'')
+		);
+	}
+
+	// Very bad
+	$zapfields[] = array($account,'account',$account);	
+	$zapfields[] = array($account,'callerid',($_REQUEST['description'])?$_REQUEST['description']." <".$account.'>':'device'." <".$account.'>');
+	
+	// Where is this in the interface ??????
+	$zapfields[] = array($account,'record_in',($_REQUEST['record_in'])?$_REQUEST['record_in']:'On-Demand');
+	$zapfields[] = array($account,'record_out',($_REQUEST['record_out'])?$_REQUEST['record_out']:'On-Demand');
+
+	$compiled = $db->prepare('INSERT INTO zap (id, keyword, data) values (?,?,?)');
+	$result = $db->executeMultiple($compiled,$zapfields);
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage()."<br><br>error adding to ZAP table");	
+	}
+}
+
+function core_devices_delzap($account) {
+	global $db;
+	global $currentFile;
+	
+	$sql = "DELETE FROM zap WHERE id = '$account'";
+	$result = $db->query($sql);
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage().$sql);
+	}
+}
+
+function core_devices_getzap($account) {
+	global $db;
+	$sql = "SELECT keyword,data FROM zap WHERE id = '$account'";
+	$results = $db->getAssoc($sql);
+	if(DB::IsError($results)) {
+		$results = null;
+	}
+	return $results;
+}
+/* end page.devices.php functions */
+
+
+
+
+function core_hint_get($account){
+	//determine what devices this user is associated with
+	$sql = "SELECT dial from devices where user = '{$account}'";
+	$results = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
+	//print_r($results);
+	
+	//create an array of strings
+	if (is_array($results)){
+		foreach ($results as $result) {
+			$dial[] = $result['dial'];
+		}
+	}
+	
+	//create a string with & delimiter
+	if (isset($dial) && is_array($dial)){
+		$hint = implode($dial,"&");
+	} else {
+		if (isset($results[0]['dial'])) {
+			$hint = $results[0]['dial'];
+		} else {
+			$hint = null;
+		}
+	}
+	
+	return $hint;
+}
+
+
+
+/* begin page.users.php functions */
+
+// get the existing extensions
+// the returned arrays contain [0]:extension [1]:name
+function core_users_list() {
+	$results = sql("SELECT extension,name,voicemail FROM users ORDER BY extension","getAll");
+
+	//only allow extensions that are within administrator's allowed range
+	foreach($results as $result){
+		if (checkRange($result[0])){
+			$extens[] = array($result[0],$result[1]);
+		}
+	}
+	
+	if (isset($extens)) {
+		sort($extens);
+		return $extens;
+	} else {
+		return null;
+	}
+}
+
+function core_sipname_check($sipname, $extension) {
+	global $db;
+	if (!isset($sipname) || trim($sipname)=='')
+		return true;
+
+	$sql = "SELECT sipname FROM users WHERE sipname = '$sipname' AND extension != '$extension'";
+	$results = $db->getRow($sql,DB_FETCHMODE_ASSOC);
+	if(DB::IsError($results)) {
+        die_freepbx($results->getMessage().$sql);
+	}
+	
+	if (isset($results['sipname']) && trim($results['sipname']) == $sipname) 
+		return false;
+	else
+		return true;
+}
+
+function core_users_add($vars) {
+	extract($vars);
+	
+	global $db;
+	global $amp_conf;
+	global $astman;
+
+	$thisexten = isset($thisexten) ? $thisexten : '';
+
+	if (trim($extension) == '' ) {
+		echo "<script>javascript:alert('"._("You must put in an extension (or user) number")."');</script>";
+		return false;
+	}
+
+	//ensure this id is not already in use
+	$extens = core_users_list();
+	if(is_array($extens)) {
+		foreach($extens as $exten) {
+			if ($exten[0]===$extension) {
+				echo "<script>javascript:alert('".sprintf(_("This user/extension %s is already in use"),$extension)."');</script>";
+				return false;
+			}
+		}
+	}
+
+	// clean and check the did to make sure it is not being used by another extension or in did routing
+	//
+	$directdid = preg_replace("/[^0-9._XxNnZz\[\]\-\+]/" ,"", trim($directdid));
+	if (trim($directdid) != "") {
+		$existing=core_did_get($directdid,"","");
+		$existing_directdid = empty($existing)?core_users_directdid_get($directdid):$existing;
+		if (!empty($existing) || !empty($existing_directdid)) {
+			if (!empty($existing)) {
+				echo "<script>javascript:alert('"._("A route with this DID already exists:")." ".$existing['extension']."')</script>";
+			} else {
+				echo "<script>javascript:alert('"._("This DID is already associated with extension:")." ".$existing_directdid['extension']." (".$existing_directdid['name'].")')</script>";
+			}
+			return false;
+		}
+	}
+
+	$sipname = preg_replace("/\s/" ,"", trim($sipname));
+	if (! core_sipname_check($sipname, $extension)) {
+		echo "<script>javascript:alert('"._("This sipname: {$sipname} is already in use")."');</script>";
+		return false;
+	}
+	
+	//build the recording variable
+	$recording = "out=".$record_out."|in=".$record_in;
+	
+	//escape quotes and any other bad chars:
+	if(!get_magic_quotes_gpc()) {
+		$outboundcid = addslashes($outboundcid);
+		$name = addslashes($name);
+	}
+
+	//if voicemail is enabled, set the box at context to use
+	//havn't checked but why is voicemail needed on users anyway?  Doesn't exactly make it modular !
+	if ( function_exists('voicemail_mailbox_get') ) {
+		$vmbox = voicemail_mailbox_get($extension);
+		if ( $vmbox == null ) {
+			$voicemail = "novm";
+			$vmx_state = "false";
+		} else {
+			$voicemail = $vmbox['vmcontext'];
+		}
+	}
+
+	// MODIFICATION: (PL)
+	// Added for directdid and didalert l for Alert Info distinctive ring)
+	//
+	// cleanup any non dial pattern characters prior to inserting into the database
+	// then add directdid to the insert command.
+	//
+	// Clean replace any <> with () in display name - should have javascript stopping this but ...
+	//
+	$name = preg_replace(array('/</','/>/'), array('(',')'), trim($name));
+	
+	//insert into users table
+	$sql="INSERT INTO users (extension,password,name,voicemail,ringtimer,noanswer,recording,outboundcid,directdid,didalert,faxexten,faxemail,answer,wait,privacyman,mohclass,sipname) values (\"";
+	$sql.= "$extension\", \"";
+	$sql.= isset($password)?$password:'';
+	$sql.= "\", \"";
+	$sql.= isset($name)?$name:'';
+	$sql.= "\", \"";
+	$sql.= isset($voicemail)?$voicemail:'default';
+	$sql.= "\", \"";
+	$sql.= isset($ringtimer)?$ringtimer:'';
+	$sql.= "\", \"";
+	$sql.= isset($noanswer)?$noanswer:'';
+	$sql.= "\", \"";
+	$sql.= isset($recording)?$recording:'';
+	$sql.= "\", \"";
+	$sql.= isset($outboundcid)?$outboundcid:'';
+	$sql.= "\", \"";
+	$sql.= isset($directdid)?$directdid:'';
+	$sql.= "\", \"";
+	$sql.= isset($didalert)?$didalert:'';
+
+	$sql.= "\", \"";
+	$sql.= isset($faxexten)?$faxexten:'';
+	$sql.= "\", \"";
+	$sql.= isset($faxemail)?$faxemail:'';
+	$sql.= "\", \"";
+	$sql.= isset($answer)?$answer:'';
+	$sql.= "\", \"";
+	$sql.= isset($wait)?$wait:'';
+	$sql.= "\", \"";
+	$sql.= isset($privacyman)?$privacyman:'';
+	$sql.= "\", \"";
+	$sql.= isset($mohclass)?$mohclass:'';
+	$sql.= "\", \"";
+	$sql.= isset($sipname)?$sipname:'';
+	$sql.= "\")";
+	sql($sql);
+
+	//write to astdb
+	if ($astman) {
+		$cid_masquerade = (isset($cid_masquerade) && trim($cid_masquerade) != "")?trim($cid_masquerade):$extension;
+		$astman->database_put("AMPUSER",$extension."/password",isset($password)?$password:'');
+		$astman->database_put("AMPUSER",$extension."/ringtimer",isset($ringtimer)?$ringtimer:'');
+		$astman->database_put("AMPUSER",$extension."/noanswer",isset($noanswer)?$noanswer:'');
+		$astman->database_put("AMPUSER",$extension."/recording",isset($recording)?$recording:'');
+		$astman->database_put("AMPUSER",$extension."/outboundcid",isset($outboundcid)?"\"".$outboundcid."\"":'');
+		$astman->database_put("AMPUSER",$extension."/cidname",isset($name)?"\"".$name."\"":'');
+		$astman->database_put("AMPUSER",$extension."/cidnum",$cid_masquerade);
+		$astman->database_put("AMPUSER",$extension."/voicemail","\"".isset($voicemail)?$voicemail:''."\"");
+		$astman->database_put("AMPUSER",$extension."/device","\"".((isset($device))?$device:'')."\"");
+
+		if (trim($callwaiting) == 'enabled') {
+			$astman->database_put("CW",$extension,"\"ENABLED\"");
+		} else if (trim($callwaiting) == 'disabled') {
+			$astman->database_del("CW",$extension);
+		} else {
+			echo "ERROR: this state should not exist<br>";
+		}
+
+		if ($vmx_state && $voicemail != "novm") {
+
+			$unavail_mode="enabled";
+			$busy_mode="disabled";
+			$vmx_state=$astman->database_get("AMPUSER",$extension."/vmx/unavail/state");
+
+			if (trim($vmx_state) == 'blocked') {
+
+				$astman->database_put("AMPUSER", "$extension/vmx/unavail/state", "$unavail_mode");
+				$astman->database_put("AMPUSER", "$extension/vmx/busy/state", "$busy_mode");
+
+			} elseif (trim($vmx_state) != 'enabled' && trim($vmx_state) != 'disabled') {
+
+				$repeat="1";
+				$timeout="2";
+				$vmxopts_timeout="";
+				$loops="1";
+
+				$mode="unavail";
+				$astman->database_put("AMPUSER", "$extension/vmx/$mode/state", "$unavail_mode");
+				$astman->database_put("AMPUSER", "$extension/vmx/$mode/repeat", "$repeat");
+				$astman->database_put("AMPUSER", "$extension/vmx/$mode/timeout", "$timeout");
+				$astman->database_put("AMPUSER", "$extension/vmx/$mode/vmxopts/timeout", "$vmxopts_timeout");
+				$astman->database_put("AMPUSER", "$extension/vmx/$mode/loops", "$loops");
+
+				$mode="busy";
+				$astman->database_put("AMPUSER", "$extension/vmx/$mode/state", "$busy_mode");
+				$astman->database_put("AMPUSER", "$extension/vmx/$mode/repeat", "$repeat");
+				$astman->database_put("AMPUSER", "$extension/vmx/$mode/timeout", "$timeout");
+				$astman->database_put("AMPUSER", "$extension/vmx/$mode/vmxopts/timeout", "$vmxopts_timeout");
+				$astman->database_put("AMPUSER", "$extension/vmx/$mode/loops", "$loops");
+				
+			}
+		} else {
+			$vmx_state=$astman->database_get("AMPUSER",$extension."/vmx/unavail/state");
+			if (trim($vmx_state) == 'enabled' || trim($vmx_state) == 'disabled' || trim($vmx_state) == 'blocked') {
+				$astman->database_put("AMPUSER", "$extension/vmx/unavail/state", "blocked");
+				$astman->database_put("AMPUSER", "$extension/vmx/busy/state", "blocked");
+			}
+		}
+	} else {
+		fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
+	}
+	return true;
+}
+
+function core_users_get($extension){
+	global $db;
+	global $amp_conf;
+	global $astman;
+	//get all the variables for the meetme
+	$sql = "SELECT * FROM users WHERE extension = '$extension'";
+	$results = $db->getRow($sql,DB_FETCHMODE_ASSOC);
+	if(DB::IsError($results)) {
+		die_freepbx($results->getMessage().$sql);
+	}
+	
+	//explode recording vars
+	$recording = explode("|",$results['recording']);
+	if (isset($recording[1])) {
+		$recout = substr($recording[0],4);
+		$recin = substr($recording[1],3);
+		$results['record_in']=$recin;
+		$results['record_out']=$recout;
+	} else {
+		$results['record_in']='Adhoc';
+		$results['record_out']='Adhoc';
+	}
+	if ($astman) {
+		$cw = $astman->database_get("CW",$extension);
+		$results['callwaiting'] = (trim($cw) == 'ENABLED') ? 'enabled' : 'disabled';
+		$results['vmx_state']=$astman->database_get("AMPUSER",$extension."/vmx/unavail/state");
+		$cid_masquerade=$astman->database_get("AMPUSER",$extension."/cidnum");
+		$results['cid_masquerade'] = (trim($cid_masquerade) != "")?$cid_masquerade:$extension;
+	} else {
+		fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
+	}
+
+	return $results;
+}
+
+function core_users_del($extension){
+	global $db;
+	global $amp_conf;
+	global $astman;
+	
+	//delete from devices table
+	$sql="DELETE FROM users WHERE extension = \"$extension\"";
+	$results = $db->query($sql);
+	if(DB::IsError($results)) {
+		die_freepbx($results->getMessage().$sql);
+	}
+
+	//delete details to astdb
+	if ($astman) {
+		$astman->database_del("AMPUSER",$extension."/password");
+		$astman->database_del("AMPUSER",$extension."/ringtimer");
+		$astman->database_del("AMPUSER",$extension."/noanswer");
+		$astman->database_del("AMPUSER",$extension."/recording");
+		$astman->database_del("AMPUSER",$extension."/outboundcid");
+		$astman->database_del("AMPUSER",$extension."/cidname");
+		$astman->database_del("AMPUSER",$extension."/cidnum");
+		$astman->database_del("AMPUSER",$extension."/voicemail");
+		$astman->database_del("AMPUSER",$extension."/device");
+	} else {
+		fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
+	}
+}
+
+function core_users_directdid_get($directdid=""){
+	if (empty($directdid)) {
+		return array();
+	} else {
+		$sql = "SELECT * FROM users WHERE directdid = \"$directdid\"";
+		return sql($sql,"getRow",DB_FETCHMODE_ASSOC);
+	}
+}
+
+function core_users_cleanastdb($extension) {
+	// This is called to remove any ASTDB traces of the user after a deletion. Otherwise,
+	// call forwarding, call waiting settings could hang around and bite someone if they
+	// recycle an extension. Is called from page.xtns and page.users.
+	global $amp_conf;
+	global $astman;
+
+	if ($astman) {
+		$astman->database_del("CW",$extension);
+		$astman->database_del("CF",$extension);
+		$astman->database_del("CFB",$extension);
+		$astman->database_del("CFU",$extension);
+		$astman->database_deltree("AMPUSER/".$extension."/vmx");
+
+	} else {
+		fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
+	}
+}
+
+function core_users_edit($extension,$vars){
+	global $db;
+	global $amp_conf;
+	global $astman;
+	
+	//I we are editing, we need to remember existing user<->device mapping, so we can delete and re-add
+	if ($astman) {
+		$ud = $astman->database_get("AMPUSER",$extension."/device");
+		$vars['device'] = $ud;
+	} else {
+		fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
+	}
+	
+	$directdid=$vars['directdid'];
+	$directdid = preg_replace("/[^0-9._XxNnZz\[\]\-\+]/" ,"", trim($directdid));
+	// clean and check the did to make sure it is not being used by another extension or in did routing
+	//
+	if (trim($directdid) != "") {
+		$existing=core_did_get($directdid,"","");
+		$existing_directdid = empty($existing)?core_users_directdid_get($directdid):$existing;
+		if (!empty($existing) || (!empty($existing_directdid) && $existing_directdid['extension'] != $extension)) {
+			if (!empty($existing)) {
+				echo "<script>javascript:alert('"._("A route with this DID already exists:")." ".$existing['extension']."')</script>";
+			} else {
+				echo "<script>javascript:alert('"._("This DID is already associated with extension:")." ".$existing_directdid['extension']." (".$existing_directdid['name'].")')</script>";
+			}
+			return false;
+		}
+	}
+
+	//delete and re-add
+	if (core_sipname_check($vars['sipname'],$extension)) {
+		core_users_del($extension);
+		core_users_add($vars);
+	}
+	return true;
+	
+}
+
+function core_directdid_list(){
+	$sql = "SELECT extension, directdid, didalert, mohclass, faxexten, faxemail, answer, wait, privacyman FROM users WHERE directdid IS NOT NULL AND directdid != ''";
+	return sql($sql,"getAll",DB_FETCHMODE_ASSOC);
+}
+
+
+
+/* end page.users.php functions */
+
+
+
+
+
+/* begin page.trunks.php functions */
+
+// we're adding ,don't require a $trunknum
+function core_trunks_add($tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register, $keepcid, $failtrunk, $disabletrunk) {
+	global $db;
+	
+	// find the next available ID
+	$trunknum = 1;
+	foreach(core_trunks_list() as $trunk) {
+		if ($trunknum == ltrim($trunk[0],"OUT_")) { 
+			$trunknum++;
+		}
+	}
+	
+	core_trunks_backendAdd($trunknum, $tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register, $keepcid, $failtrunk, $disabletrunk);
+	
+	return $trunknum;
+}
+
+function core_trunks_del($trunknum, $tech = null) {
+	global $db;
+	
+	if ($tech === null) { // in EditTrunk, we get this info anyways
+		$tech = core_trunks_getTrunkTech($trunknum);
+	}
+
+	//delete from globals table
+	sql("DELETE FROM globals WHERE variable LIKE '%OUT_$trunknum' OR variable IN ('OUTCID_$trunknum','OUTMAXCHANS_$trunknum','OUTPREFIX_$trunknum','OUTKEEPCID_$trunknum','OUTFAIL_$trunknum','OUTDISABLE_$trunknum')");
+	
+	//write outids
+	core_trunks_writeoutids();
+
+	// conditionally, delete from iax or sip
+	switch (strtolower($tech)) {
+		case "iax":
+		case "iax2":
+			sql("DELETE FROM iax WHERE id = '9999$trunknum' OR id = '99999$trunknum' OR id = '9999999$trunknum'");
+		break;
+		case "sip": 
+			sql("DELETE FROM sip WHERE id = '9999$trunknum' OR id = '99999$trunknum' OR id = '9999999$trunknum'");
+		break;
+	}
+}
+
+function core_trunks_edit($trunknum, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register, $keepcid, $failtrunk, $disabletrunk) {
+	//echo "editTrunk($trunknum, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register)";
+	$tech = core_trunks_getTrunkTech($trunknum);
+	core_trunks_del($trunknum, $tech);
+	core_trunks_backendAdd($trunknum, $tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register, $keepcid, $failtrunk, $disabletrunk);
+}
+
+// just used internally by addTrunk() and editTrunk()
+//obsolete
+function core_trunks_backendAdd($trunknum, $tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register, $keepcid, $failtrunk, $disabletrunk) {
+	global $db;
+	
+	if  (is_null($dialoutprefix)) $dialoutprefix = ""; // can't be NULL
+	
+	//echo  "backendAddTrunk($trunknum, $tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register)";
+	
+	// change iax to "iax2" (only spot we actually store iax2, since its used by Dial()..)
+	$techtemp = ((strtolower($tech) == "iax") ? "iax2" : $tech);
+	$outval = (($techtemp == "custom") ? "AMP:".$channelid : strtoupper($techtemp).'/'.$channelid);
+	
+	$glofields = array(
+			array('OUT_'.$trunknum, $outval),
+			array('OUTPREFIX_'.$trunknum, $dialoutprefix),
+			array('OUTMAXCHANS_'.$trunknum, $maxchans),
+			array('OUTCID_'.$trunknum, $outcid),
+			array('OUTKEEPCID_'.$trunknum, $keepcid),
+			array('OUTFAIL_'.$trunknum, $failtrunk),
+			array('OUTDISABLE_'.$trunknum, $disabletrunk),
+			);
+			
+	unset($techtemp); 
+	
+	$compiled = $db->prepare('INSERT INTO globals (variable, value) values (?,?)');
+	$result = $db->executeMultiple($compiled,$glofields);
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage()."<br><br>".$sql);
+	}
+	
+	core_trunks_writeoutids();
+
+	$disable_flag = ($disabletrunk == "on")?1:0;
+	
+	switch (strtolower($tech)) {
+		case "iax":
+		case "iax2":
+			core_trunks_addSipOrIax($peerdetails,'iax',$channelid,$trunknum,$disable_flag);
+			if ($usercontext != ""){
+				core_trunks_addSipOrIax($userconfig,'iax',$usercontext,'9'.$trunknum,$disable_flag);
+			}
+			if ($register != ""){
+				core_trunks_addRegister($trunknum,'iax',$register,$disable_flag);
+			}
+		break;
+		case "sip":
+			core_trunks_addSipOrIax($peerdetails,'sip',$channelid,$trunknum,$disable_flag);
+			if ($usercontext != ""){
+				core_trunks_addSipOrIax($userconfig,'sip',$usercontext,'9'.$trunknum,$disable_flag);
+			}
+			if ($register != ""){
+				core_trunks_addRegister($trunknum,'sip',$register,$disable_flag);
+			}
+		break;
+	}	
+}
+
+function core_trunks_getTrunkTech($trunknum) {
+
+	$results = sql("SELECT value FROM globals WHERE variable = 'OUT_".$trunknum."'","getAll");
+	if (!$results) {
+		return false;
+	}
+	if(strpos($results[0][0],"AMP:") === 0) {  //custom trunks begin with AMP:
+		$tech = "custom";
+	} else {
+		$tech = strtolower( strtok($results[0][0],'/') ); // the technology.  ie: ZAP/g0 is ZAP
+		
+		if ($tech == "iax2") $tech = "iax"; // same thing, here
+	}
+	return $tech;
+}
+
+//add trunk info to sip or iax table
+function core_trunks_addSipOrIax($config,$table,$channelid,$trunknum,$disable_flag=0) {
+	global $db;
+	
+	$confitem['account'] = $channelid;
+	$gimmieabreak = nl2br($config);
+	$lines = split('<br />',$gimmieabreak);
+	foreach ($lines as $line) {
+		$line = trim($line);
+		if (count(split('=',$line)) > 1) {
+			$tmp = split('=',$line,2);
+			$key=trim($tmp[0]);
+			$value=trim($tmp[1]);
+			if (isset($confitem[$key]) && !empty($confitem[$key]))
+				$confitem[$key].="&".$value;
+			else
+				$confitem[$key]=$value;
+		}
+	}
+	foreach($confitem as $k=>$v) {
+		$dbconfitem[]=array($k,$v);
+	}
+	$compiled = $db->prepare("INSERT INTO $table (id, keyword, data, flags) values ('9999$trunknum',?,?,'$disable_flag')");
+	$result = $db->executeMultiple($compiled,$dbconfitem);
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage()."<br><br>INSERT INTO $table (id, keyword, data, flags) values ('9999$trunknum',?,?,'$disable_flag')");	
+	}
+}
+
+//get unique trunks
+function core_trunks_list($assoc = false) {
+	// TODO: $assoc default to true, eventually..
+
+	global $db;
+	global $amp_conf;
+	
+	if ($amp_conf["AMPDBENGINE"] == "sqlite3")
+	{
+		// 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\_%' ";
+		$sqlstr .= "UNION ALL ";
+		$sqlstr .= "SELECT v.variable, v.value, concat(substring(v.value,1,0),'off') state  FROM `globals` v ";
+		$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"); 
+	}
+	else
+	{
+		// we have to escape _ for mysql: normally a wildcard
+		$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\\\_%' ";
+		$sqlstr .= "UNION ALL ";
+		$sqlstr .= "SELECT v.variable, v.value, concat(substring(v.value,1,0),'off') state  FROM `globals` v ";
+		$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 RIGHT( variable, LENGTH( variable ) - 4 )+0";
+
+		//$unique_trunks = sql("SELECT * FROM globals WHERE variable LIKE 'OUT\\\_%' ORDER BY RIGHT( variable, LENGTH( variable ) - 4 )+0","getAll"); 
+		$unique_trunks = sql($sqlstr,"getAll"); 
+	}
+
+	//if no trunks have ever been defined, then create the proper variables with the default zap trunk
+	if (count($unique_trunks) == 0) 
+	{
+		//If all trunks have been deleted from admin, dialoutids might still exist
+		sql("DELETE FROM globals WHERE variable = 'DIALOUTIDS'");
+	
+		$glofields = array(array('OUT_1','ZAP/g0'),
+							array('DIAL_OUT_1','9'),
+							array('DIALOUTIDS','1'));
+		$compiled = $db->prepare('INSERT INTO globals (variable, value) values (?,?)');
+		$result = $db->executeMultiple($compiled,$glofields);
+		if(DB::IsError($result))
+		{
+			die_freepbx($result->getMessage()."<br><br>".$sql);	
+		}
+		$unique_trunks[] = array('OUT_1','ZAP/g0');
+	}
+	// asort($unique_trunks);
+
+	if ($assoc) {
+		$trunkinfo = array();
+
+		foreach ($unique_trunks as $trunk) {
+			list($tech,$name) = explode('/',$trunk[1]);
+			$trunkinfo[$name] = array(
+				'name' => $name,
+				'tech' => $tech,
+				'globalvar' => $trunk[0], // ick
+				'value' => $trunk[2], // ??  no idea what this is.
+			);	
+		}
+		return $trunkinfo;
+	} else {
+		return $unique_trunks;
+	}
+}
+
+//write the OUTIDS global variable (used in dialparties.agi)
+function core_trunks_writeoutids() {
+	// we have to escape _ for mysql: normally a wildcard
+	$unique_trunks = sql("SELECT variable FROM globals WHERE variable LIKE 'OUT\\\_%'","getAll"); 
+
+	$outids = null; // Start off with nothing
+	foreach ($unique_trunks as $unique_trunk) {
+		$outid = strtok($unique_trunk[0],"_");
+		$outid = strtok("_");
+		$outids .= $outid ."/";
+	}
+	
+	sql("UPDATE globals SET value = '$outids' WHERE variable = 'DIALOUTIDS'");
+}
+
+function core_trunks_addRegister($trunknum,$tech,$reg,$disable_flag=0) {
+	sql("INSERT INTO $tech (id, keyword, data, flags) values ('9999999$trunknum','register','$reg','$disable_flag')");
+}
+
+
+function core_trunks_addDialRules($trunknum, $dialrules) {
+	$values = array();
+	$i = 1;
+	foreach ($dialrules as $rule) {
+		$values["rule".$i++] = $rule;
+	}
+	
+	$conf = core_trunks_readDialRulesFile();
+	
+	// rewrite for this trunk
+	$conf["trunk-".$trunknum] = $values;
+	
+	core_trunks_writeDialRulesFile($conf);
+}
+
+function core_trunks_readDialRulesFile() {
+	global $amp_conf;
+	$localPrefixFile = $amp_conf['ASTETCDIR']."/localprefixes.conf";
+	
+	core_trunks_parse_conf($localPrefixFile, $conf, $section);
+	
+	return $conf;
+}
+
+function core_trunks_writeDialRulesFile($conf) {
+	global $amp_conf;
+	$localPrefixFile = $amp_conf['ASTETCDIR']."/localprefixes.conf";
+	
+	$fd = fopen($localPrefixFile,"w");
+	foreach ($conf as $section=>$values) {
+		fwrite($fd, "[".$section."]\n");
+		foreach ($values as $key=>$value) {
+			fwrite($fd, $key."=".$value."\n");
+		}
+		fwrite($fd, "\n");
+	}
+	fclose($fd);
+}
+
+function core_trunks_parse_conf($filename, &$conf, &$section) {
+	if (is_null($conf)) {
+		$conf = array();
+	}
+	if (is_null($section)) {
+		$section = "general";
+	}
+	
+	if (file_exists($filename)) {
+		$fd = fopen($filename, "r");
+		while ($line = fgets($fd, 1024)) {
+			if (preg_match("/^\s*([a-zA-Z0-9-_]+)\s*=\s*(.*?)\s*([;#].*)?$/",$line,$matches)) {
+				// name = value
+				// option line
+				$conf[$section][ $matches[1] ] = $matches[2];
+			} else if (preg_match("/^\s*\[(.+)\]/",$line,$matches)) {
+				// section name
+				$section = strtolower($matches[1]);
+			} else if (preg_match("/^\s*#include\s+(.*)\s*([;#].*)?/",$line,$matches)) {
+				// include another file
+				
+				if ($matches[1][0] == "/") {
+					// absolute path
+					$filename = $matches[1];
+				} else {
+					// relative path
+					$filename =  dirname($filename)."/".$matches[1];
+				}
+				
+				core_trunks_parse_conf($filename, $conf, $section);
+			}
+		}
+	}
+}
+
+function core_trunks_getTrunkTrunkName($trunknum) {
+	$results = sql("SELECT value FROM globals WHERE variable = 'OUT_".$trunknum."'","getAll");
+	if (!$results) {
+		return false;
+	}
+	
+	if(strpos($results[0][0],"AMP:") === 0) {  //custom trunks begin with AMP:
+		$tname = substr($results[0][0],4);
+	} else {
+	strtok($results[0][0],'/');
+		$tname = strtok('/'); // the text _after_ technology.  ie: ZAP/g0 is g0
+	}
+	return $tname;
+}
+
+//get and print peer details (prefixed with 4 9's)
+function core_trunks_getTrunkPeerDetails($trunknum) {
+	global $db;
+	
+	$tech = core_trunks_getTrunkTech($trunknum);
+	
+	if ($tech == "zap") return ""; // zap has no details
+	
+	$results = sql("SELECT keyword,data FROM $tech WHERE id = '9999$trunknum' ORDER BY id","getAll");
+	
+	foreach ($results as $result) {
+		if ($result[0] != 'account') {
+			if (isset($confdetail))
+				$confdetail .= $result[0] .'='. $result[1] . "\n";
+			else
+				$confdetail = $result[0] .'='. $result[1] . "\n";
+		}
+	}
+	return $confdetail;
+}
+
+//get trunk user context (prefixed with 5 9's)
+function core_trunks_getTrunkUserContext($trunknum) {
+	$tech = core_trunks_getTrunkTech($trunknum);
+	if ($tech == "zap") return ""; // zap has no account
+	
+	$results = sql("SELECT keyword,data FROM $tech WHERE id = '99999$trunknum' ORDER BY id","getAll");
+
+	foreach ($results as $result) {
+		if ($result[0] == 'account') {
+			$account = $result[1];
+		}
+	}
+	return isset($account)?$account:null;
+}
+
+//get and print user config (prefixed with 5 9's)
+function core_trunks_getTrunkUserConfig($trunknum) {
+	global $db;
+	
+	$tech = core_trunks_getTrunkTech($trunknum);
+	
+	if ($tech == "zap") return ""; // zap has no details
+	
+	$results = sql("SELECT keyword,data FROM $tech WHERE id = '99999$trunknum' ORDER BY id","getAll");
+
+	foreach ($results as $result) {
+		if ($result[0] != 'account') {
+			if (isset($confdetail))
+				$confdetail .= $result[0] .'='. $result[1] . "\n";
+			else
+				$confdetail = $result[0] .'='. $result[1] . "\n";
+		}
+	}
+	return isset($confdetail)?$confdetail:null;
+}
+
+//get trunk account register string
+function core_trunks_getTrunkRegister($trunknum) {
+	$tech = core_trunks_getTrunkTech($trunknum);
+	
+	if ($tech == "zap") return ""; // zap has no register
+	
+	$results = sql("SELECT keyword,data FROM $tech WHERE id = '9999999$trunknum'","getAll");
+
+	foreach ($results as $result) {
+			$register = $result[1];
+	}
+	return isset($register)?$register:null;
+}
+
+function core_trunks_getDialRules($trunknum) {
+	$conf = core_trunks_readDialRulesFile();
+	if (isset($conf["trunk-".$trunknum])) {
+		return $conf["trunk-".$trunknum];
+	}
+	return false;
+}
+
+//get outbound routes for a given trunk
+function core_trunks_gettrunkroutes($trunknum) {
+	global $amp_conf;
+
+	if ($amp_conf["AMPDBENGINE"] == "sqlite3")
+		$sql_code = "SELECT DISTINCT              context, priority FROM extensions WHERE context LIKE 'outrt-%' AND (args LIKE 'dialout-trunk,".$trunknum.",%' OR args LIKE 'dialout-enum,".$trunknum.",%') ORDER BY context";
+	else
+		$sql_code = "SELECT DISTINCT SUBSTRING(context,7), priority FROM extensions WHERE context LIKE 'outrt-%' AND (args LIKE 'dialout-trunk,".$trunknum.",%' OR args LIKE 'dialout-enum,".$trunknum.",%') ORDER BY context";
+
+	$results = sql( $sql_code, "getAll" );
+
+	foreach ($results as $row) {
+		// original code was:
+		// 	$routes[$row[0]] = $row[1];
+		// but substring is not supported in sqlite3.
+		// how about we remove the 2nd part of the "if"? and use the same code on all DB's?
+
+		$t = ($amp_conf["AMPDBENGINE"] == "sqlite3") ? substr( $row[0], 7 ) : $row[0];
+		$r = $row[1];
+		$routes[ $r ] = $t;
+
+	}
+	// array(routename=>priority)
+	return isset($routes)?$routes:null;
+}
+
+function core_trunks_deleteDialRules($trunknum) {
+	$conf = core_trunks_readDialRulesFile();
+	
+	// remove rules for this trunk
+	unset($conf["trunk-".$trunknum]);
+	
+	core_trunks_writeDialRulesFile($conf);
+}
+
+/* end page.trunks.php functions */
+
+
+/* begin page.routing.php functions */
+
+//get unique outbound route names
+function core_routing_getroutenames() 
+{
+	global $amp_conf;
+	
+	if ($amp_conf["AMPDBENGINE"] == "sqlite3") 
+	{
+		// SUBSTRING is not supported under sqlite3, we need to filter
+		// this in php. I am not sure why "6" and not "7"
+		// but I don't really care -> it works :)
+		$results = sql("SELECT DISTINCT context FROM extensions WHERE context LIKE 'outrt-%' ORDER BY context ","getAll");
+		foreach( array_keys($results) as $idx )
+		{
+			 $results[$idx][0] = substr( $results[$idx][0], 6);
+		}
+	}
+	else
+	{
+		// we SUBSTRING() to remove "outrt-"
+		$results = sql("SELECT DISTINCT SUBSTRING(context,7) FROM extensions WHERE context LIKE 'outrt-%' ORDER BY context ","getAll");
+	}
+
+
+	//TODO: This needs to be yanked, should be in the upgrade script somewhere not here
+	//
+	if (count($results) == 0) {
+		// see if they're still using the old dialprefix method
+		$results = sql("SELECT variable,value FROM globals WHERE variable LIKE 'DIAL\\\_OUT\\\_%'","getAll");
+		// we SUBSTRING() to remove "outrt-"
+		
+		if (count($results) > 0) {
+			// yes, they are using old method, let's update
+			
+			// get the default trunk
+			$results_def = sql("SELECT value FROM globals WHERE variable = 'OUT'","getAll");
+			
+			if (preg_match("/{OUT_(\d+)}/", $results_def[0][0], $matches)) {
+				$def_trunk = $matches[1];
+			} else {
+				$def_trunk = "";
+			}
+			
+			$default_patterns = array(	// default patterns that used to be in extensions.conf
+						"NXXXXXX",
+						"NXXNXXXXXX",
+						"1800NXXXXXX",
+						"1888NXXXXXX",
+						"1877NXXXXXX",
+						"1866NXXXXXX",
+						"1NXXNXXXXXX",
+						"011.",
+						"911",
+						"411",
+						"311",
+						);
+			
+			foreach ($results as $temp) {
+				// temp[0] is "DIAL_OUT_1"
+				// temp[1] is the dial prefix
+				
+				$trunknum = substr($temp[0],9);
+				
+				$name = "route".$trunknum;
+				
+				$trunks = array(1=>"OUT_".$trunknum); // only one trunk to use
+				
+				$patterns = array();
+				foreach ($default_patterns as $pattern) {
+					$patterns[] = $temp[1]."|".$pattern;
+				}
+				
+				if ($trunknum == $def_trunk) {
+					// this is the default trunk, add the patterns with no prefix
+					$patterns = array_merge($patterns, $default_patterns);
+				}
+				
+				// add this as a new route
+				core_routing_add($name, $patterns, $trunks,"new");
+			}
+			
+			
+			// delete old values
+			sql("DELETE FROM globals WHERE (variable LIKE 'DIAL\\\_OUT\\\_%') OR (variable = 'OUT') ");
+
+			// we need to re-generate extensions_additional.conf
+			// i'm not sure how to do this from here
+			
+			// re-run our query
+			$results = sql("SELECT DISTINCT SUBSTRING(context,7) FROM extensions WHERE context LIKE 'outrt-%' ORDER BY context ","getAll");
+			// we SUBSTRING() to remove "outrt-"
+		}
+		
+	} // else, it just means they have no routes.
+	
+	return $results;
+}
+
+function core_routing_setroutepriority($routepriority, $reporoutedirection, $reporoutekey)
+{
+	global $db, $amp_conf;
+	$counter=-1;
+	foreach ($routepriority as $tresult) 
+	{
+		$counter++;
+		if (($counter==($reporoutekey-1)) && ($reporoutedirection=="up")) {
+			// swap this one with the one before (move up)
+			$temproute = $routepriority[$counter];
+			$routepriority[ $counter ] = $routepriority[ $counter+1 ];
+			$routepriority[ $counter+1 ] = $temproute;
+			
+		} else if (($counter==($reporoutekey)) && ($reporoutedirection=="down")) {
+			// swap this one with the one after (move down)
+			$temproute = $routepriority[ $counter+1 ];
+			$routepriority[ $counter+1 ] = $routepriority[ $counter ];
+			$routepriority[ $counter ] = $temproute;
+		}
+	}
+	unset($temptrunk);
+	$routepriority = array_values($routepriority); // resequence our numbers
+	$counter=0;
+	foreach ($routepriority as $tresult) {
+		$order=core_routing_setroutepriorityvalue($counter++);
+		$sql = sprintf("Update extensions set context='outrt-%s-%s' WHERE context='outrt-%s'",$order,substr($tresult[0],4), $tresult[0]);
+		$result = $db->query($sql); 
+		if(DB::IsError($result)) {     
+			die_freepbx($result->getMessage()); 
+		}
+	}
+	
+	// Delete and readd the outbound-allroutes entries
+	$sql = "delete from  extensions WHERE context='outbound-allroutes'";
+	$result = $db->query($sql);
+	if(DB::IsError($result)) {
+        	die_freepbx($result->getMessage().$sql);
+	}
+	
+	$sql = "SELECT DISTINCT context FROM extensions WHERE context like 'outrt-%' ORDER BY context";
+	$results = $db->getAll($sql);
+	if(DB::IsError($results)) {
+		die_freepbx($results->getMessage());
+	}
+
+	$priority_loops=1;	
+	foreach ($results as $row) {
+		$sql = "INSERT INTO extensions (context, extension, priority, application, args, descr, flags) VALUES ";
+		$sql .= "('outbound-allroutes', ";
+		$sql .= "'include', ";
+		$sql .= "'".$priority_loops++."', ";
+		$sql .= "'".$row[0]."', ";
+		$sql .= "'', ";
+		$sql .= "'', ";
+		$sql .= "'2')";
+	
+		//$sql = sprintf("Update extensions set application='outrt-%s-%s' WHERE context='outbound-allroutes' and  application='outrt-%s'",$order,substr($tresult[0],4), $tresult[0]);
+		$result = $db->query($sql); 
+		if(DB::IsError($result)) {     
+			die_freepbx($result->getMessage(). $sql); 
+ 		}
+	}
+	
+	if ( $amp_conf["AMPDBENGINE"] == "sqlite3")
+		$sql = "SELECT DISTINCT context FROM extensions WHERE context LIKE 'outrt-%' ORDER BY context ";
+	else
+		$sql = "SELECT DISTINCT SUBSTRING(context,7) FROM extensions WHERE context LIKE 'outrt-%' ORDER BY context ";
+
+        // we SUBSTRING() to remove "outrt-"
+        $routepriority = $db->getAll($sql);
+        if(DB::IsError($routepriority)) {
+                die_freepbx($routepriority->getMessage());
+        }
+
+	// TODO: strip the context on the sqlite3 backend
+	// not sure where does it effects, since this is working on my setup...
+	// welcome to funky town
+        return ($routepriority);
+}
+
+function core_routing_setroutepriorityvalue($key)
+{
+	$key=$key+1;
+	if ($key<10)
+		$prefix = sprintf("00%d",$key);
+	else if ((9<$key)&&($key<100))
+		$prefix = sprintf("0%d",$key);
+	else if ($key>100)
+		$prefix = sprintf("%d",$key);
+	return ($prefix);
+}
+
+
+function core_routing_add($name, $patterns, $trunks, $method, $pass, $emergency = "", $intracompany = "", $mohsilence = "") {
+
+	global $db;
+
+	$trunktech=array();
+
+	//Retrieve each trunk tech for later lookup
+	$sql="select * from globals WHERE variable LIKE 'OUT\\_%'";
+        $result = $db->getAll($sql);
+        if(DB::IsError($result)) {
+		die_freepbx($result->getMessage());
+	}
+	foreach($result as $tr) {
+		$tech = strtok($tr[1], "/");
+		$trunktech[$tr[0]]=$tech;
+	}
+	
+ 	if ($method=="new") {	
+		$sql="select DISTINCT context FROM extensions WHERE context LIKE 'outrt-%' ORDER BY context";
+		$routepriority = $db->getAll($sql);
+		if(DB::IsError($result)) {
+			die_freepbx($result->getMessage());
+		}
+		$order=core_routing_setroutepriorityvalue(count($routepriority));
+		$name = sprintf ("%s-%s",$order,$name);
+	}
+	$trunks = array_values($trunks); // probably already done, but it's important for our dialplan
+
+	
+	foreach ($patterns as $pattern) {
+		if (false !== ($pos = strpos($pattern,"|"))) {
+			// we have a | meaning to not pass the digits on
+			// (ie, 9|NXXXXXX should use the pattern _9NXXXXXX but only pass NXXXXXX, not the leading 9)
+			
+			$pattern = str_replace("|","",$pattern); // remove all |'s
+			$exten = "EXTEN:".$pos; // chop off leading digit
+		} else {
+			// we pass the full dialed number as-is
+			$exten = "EXTEN"; 
+		}
+		
+		if (!preg_match("/^[0-9*]+$/",$pattern)) { 
+			// note # is not here, as asterisk doesn't recoginize it as a normal digit, thus it requires _ pattern matching
+			
+			// it's not strictly digits, so it must have patterns, so prepend a _
+			$pattern = "_".$pattern;
+		}
+		
+		// 1st priority is emergency dialing variable (if set)
+		if(!empty($emergency)) {
+			$startpriority = 1;
+			$sql = "INSERT INTO extensions (context, extension, priority, application, args, descr) VALUES ";
+			$sql .= "('outrt-".$name."', ";
+			$sql .= "'".$pattern."', ";
+			$sql .= "'".$startpriority."', ";
+			$sql .= "'SetVar', ";
+			$sql .= "'EMERGENCYROUTE=YES', ";
+			$sql .= "'Use Emergency CID for device')";
+			$result = $db->query($sql);
+			if(DB::IsError($result)) {
+				die_freepbx($result->getMessage());
+			}
+		} else {
+			$startpriority = 0;
+		}
+
+		// Next Priority (either first or second depending on above)
+		if(!empty($intracompany)) {
+			   $startpriority += 1;
+			   $sql = "INSERT INTO extensions (context, extension, priority, application, args, descr) VALUES ";
+			   $sql .= "('outrt-".$name."', ";
+			   $sql .= "'".$pattern."', ";
+			   $sql .= "'".$startpriority."', ";
+			   $sql .= "'SetVar', ";
+			   $sql .= "'INTRACOMPANYROUTE=YES', ";
+			   $sql .= "'Preserve Intenal CID Info')";
+			   $result = $db->query($sql);
+				if(DB::IsError($result)) {
+					   die_freepbx($result->getMessage());
+				}
+		}
+
+		// Next Priority (either first, second or third depending on above)
+		if(!empty($mohsilence) && trim($mohsilence) != 'default') {
+			   $startpriority += 1;
+			   $sql = "INSERT INTO extensions (context, extension, priority, application, args, descr) VALUES ";
+			   $sql .= "('outrt-".$name."', ";
+			   $sql .= "'".$pattern."', ";
+			   $sql .= "'".$startpriority."', ";
+			   $sql .= "'SetVar', ";
+			   $sql .= "'MOHCLASS=".$mohsilence."', ";
+			   $sql .= "'Do not play moh on this route')";
+			   $result = $db->query($sql);
+				if(DB::IsError($result)) {
+					   die_freepbx($result->getMessage());
+				}
+		}
+
+		$first_trunk = 1;
+		foreach ($trunks as $priority => $trunk) {
+			$priority += $startpriority;
+			$priority += 1; // since arrays are 0-based, but we want priorities to start at 1
+			
+			$sql = "INSERT INTO extensions (context, extension, priority, application, args) VALUES ";
+			$sql .= "('outrt-".$name."', ";
+			$sql .= "'".$pattern."', ";
+			$sql .= "'".$priority."', ";
+			$sql .= "'Macro', ";
+			if ($first_trunk)
+				$pass_str = $pass;
+			else
+				$pass_str = "";
+
+			if ($trunktech[$trunk] == "ENUM")
+				$sql .= "'dialout-enum,".substr($trunk,4).",\${".$exten."},".$pass_str."'"; // cut off OUT_ from $trunk
+			else
+				$sql .= "'dialout-trunk,".substr($trunk,4).",\${".$exten."},".$pass_str."'"; // cut off OUT_ from $trunk
+			$sql .= ")";
+			
+			$result = $db->query($sql);
+			if(DB::IsError($result)) {
+				die_freepbx($result->getMessage());
+			}
+			//To identify the first trunk in a pattern
+			//so that passwords are in the first trunk in
+			//each pattern
+			$first_trunk = 0;
+		}
+		
+		$priority += 1;
+		$sql = "INSERT INTO extensions (context, extension, priority, application, args, descr) VALUES ";
+		$sql .= "('outrt-".$name."', ";
+		$sql .= "'".$pattern."', ";
+		$sql .= "'".$priority."', ";
+		$sql .= "'Macro', ";
+		$sql .= "'outisbusy', ";
+		$sql .= "'No available circuits')";
+		
+		$result = $db->query($sql);
+		if(DB::IsError($result)) {
+			die_freepbx($result->getMessage());
+		}
+	}
+
+	
+	// add an include=>outrt-$name  to [outbound-allroutes]:
+	
+	// we have to find the first available priority.. priority doesn't really matter for the include, but
+	// there is a unique index on (context,extension,priority) so if we don't do this we can't put more than
+	// one route in the outbound-allroutes context.
+	$sql = "SELECT priority FROM extensions WHERE context = 'outbound-allroutes' AND extension = 'include'";
+	$results = $db->getAll($sql);
+	if(DB::IsError($results)) {
+		die_freepbx($results->getMessage());
+	}
+	$priorities = array();
+	foreach ($results as $row) {
+		$priorities[] = $row[0];
+	}
+	for ($priority = 1; in_array($priority, $priorities); $priority++);
+	
+	// $priority should now be the lowest available number
+	
+	$sql = "INSERT INTO extensions (context, extension, priority, application, args, descr, flags) VALUES ";
+	$sql .= "('outbound-allroutes', ";
+	$sql .= "'include', ";
+	$sql .= "'".$priority."', ";
+	$sql .= "'outrt-".$name."', ";
+	$sql .= "'', ";
+	$sql .= "'', ";
+	$sql .= "'2')";
+	
+	$result = $db->query($sql);
+	if(DB::IsError($result)) {
+		die_freepbx($priority.$result->getMessage());
+	}
+	
+}
+
+function core_routing_edit($name, $patterns, $trunks, $pass, $emergency="", $intracompany = "", $mohsilence="") {
+	core_routing_del($name);
+	core_routing_add($name, $patterns, $trunks,"edit", $pass, $emergency, $intracompany, $mohsilence);
+}
+
+function core_routing_del($name) {
+	global $db;
+	$sql = "DELETE FROM extensions WHERE context = 'outrt-".$name."'";
+	$result = $db->query($sql);
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage());
+	}
+	
+	$sql = "DELETE FROM extensions WHERE context = 'outbound-allroutes' AND application = 'outrt-".$name."' ";
+	$result = $db->query($sql);
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage());
+	}
+	
+	return $result;
+}
+
+function core_routing_rename($oldname, $newname) {
+	global $db;
+
+	$route_prefix=substr($oldname,0,4);
+	$newname=$route_prefix.$newname;
+	$sql = "SELECT context FROM extensions WHERE context = 'outrt-".$newname."'";
+	$results = $db->getAll($sql);
+	if (count($results) > 0) {
+		// there's already a route with this name
+		return false;
+	}
+	
+	$sql = "UPDATE extensions SET context = 'outrt-".$newname."' WHERE context = 'outrt-".$oldname."'";
+	$result = $db->query($sql);
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage());
+	}
+        $mypriority=sprintf("%d",$route_prefix);	
+	$sql = "UPDATE extensions SET application = 'outrt-".$newname."', priority = '$mypriority' WHERE context = 'outbound-allroutes' AND application = 'outrt-".$oldname."' ";
+	$result = $db->query($sql);
+	if(DB::IsError($result)) {
+		die_freepbx($result->getMessage());
+	}
+	
+	return true;
+}
+
+//get unique outbound route patterns for a given context
+function core_routing_getroutepatterns($route) {
+	global $db;
+	$sql = "SELECT extension, args FROM extensions WHERE context = 'outrt-".$route."' AND (args LIKE 'dialout-trunk%' OR args LIKE'dialout-enum%') ORDER BY extension ";
+	$results = $db->getAll($sql);
+	if(DB::IsError($results)) {
+		die_freepbx($results->getMessage());
+	}
+	
+	$patterns = array();
+	foreach ($results as $row) {
+		if ($row[0][0] == "_") {
+			// remove leading _
+			$pattern = substr($row[0],1);
+		} else {
+			$pattern = $row[0];
+		}
+		
+		if (preg_match("/{EXTEN:(\d+)}/", $row[1], $matches)) {
+			// this has a digit offset, we need to insert a |
+			$pattern = substr($pattern,0,$matches[1])."|".substr($pattern,$matches[1]);
+		}
+		
+		$patterns[] = $pattern;
+	}
+	return array_unique($patterns);
+}
+
+//get unique outbound route trunks for a given context
+function core_routing_getroutetrunks($route) {
+	global $db;
+	$sql = "SELECT DISTINCT args FROM extensions WHERE context = 'outrt-".$route."' AND (args LIKE 'dialout-trunk,%' OR args LIKE 'dialout-enum,%') ORDER BY CAST(priority as UNSIGNED) ";
+	$results = $db->getAll($sql);
+	if(DB::IsError($results)) {
+		die_freepbx($results->getMessage());
+	}
+	
+	$trunks = array();
+	foreach ($results as $row) {
+		if (preg_match('/^dialout-trunk,(\d+)/', $row[0], $matches)) {
+			// check in_array -- even though we did distinct
+			// we still might get ${EXTEN} and ${EXTEN:1} if they used | to split a pattern
+			if (!in_array("OUT_".$matches[1], $trunks)) {
+				$trunks[] = "OUT_".$matches[1];
+			}
+		} else if (preg_match('/^dialout-enum,(\d+)/', $row[0], $matches)) {
+			if (!in_array("OUT_".$matches[1], $trunks)) {
+				$trunks[] = "OUT_".$matches[1];
+			}
+		}
+	}
+	return $trunks;
+}
+
+
+//get password for this route
+function core_routing_getroutepassword($route) {
+	global $db;
+	$sql = "SELECT DISTINCT args FROM extensions WHERE context = 'outrt-".$route."' AND (args LIKE 'dialout-trunk,%' OR args LIKE 'dialout-enum,%') ORDER BY CAST(priority as UNSIGNED) ";
+	$results = $db->getOne($sql);
+	if(DB::IsError($results)) {
+		die_freepbx($results->getMessage());
+	}
+	if (preg_match('/^.*,.*,.*,(\d+|\/\S+)/', $results, $matches)) {
+		$password = $matches[1];
+	} else {
+		$password = "";
+	}
+	
+	return $password;
+}
+
+//get emergency state for this route
+function core_routing_getrouteemergency($route) {
+	global $db;
+	$sql = "SELECT DISTINCT args FROM extensions WHERE context = 'outrt-".$route."' AND (args LIKE 'EMERGENCYROUTE%') ";
+	$results = $db->getOne($sql);
+	if(DB::IsError($results)) {
+		die_freepbx($results->getMessage());
+	}
+	if (preg_match('/^.*=(.*)/', $results, $matches)) {
+		$emergency = $matches[1];
+	} else {
+		$emergency = "";
+	}
+	
+	return $emergency;
+}
+
+//get intracompany routing status for this route
+function core_routing_getrouteintracompany($route) {
+
+       global $db;
+       $sql = "SELECT DISTINCT args FROM extensions WHERE context = 'outrt-".$route."' AND (args LIKE 'INTRACOMPANYROUTE%') ";
+       $results = $db->getOne($sql);
+       if(DB::IsError($results)) {
+               die_freepbx($results->getMessage());
+       }
+       if (preg_match('/^.*=(.*)/', $results, $matches)) {
+               $intracompany = $matches[1];
+       } else {
+               $intracompany = "";
+       }
+       return $intracompany;
+}
+
+//get mohsilence routing status for this route
+function core_routing_getroutemohsilence($route) {
+
+       global $db;
+       $sql = "SELECT DISTINCT args FROM extensions WHERE context = 'outrt-".$route."' AND (args LIKE 'MOHCLASS%') ";
+       $results = $db->getOne($sql);
+       if(DB::IsError($results)) {
+               die_freepbx($results->getMessage());
+       }
+       if (preg_match('/^.*=(.*)/', $results, $matches)) {
+               $mohsilence = $matches[1];
+       } else {
+               $mohsilence = "";
+       }
+       return $mohsilence;
+}
+
+function general_get_zonelist() {
+	return array(
+ array ( "name" => "Austria",  "iso" => "at", "conf" => "ringcadence = 1000,5000\ndial = 420\nbusy = 420/400,0/400\nring = 420/1000,0/5000\ncongestion = 420/200,0/200\ncallwaiting = 420/40,0/1960\ndialrecall = 420\nrecord = 1400/80,0/14920\ninfo = 950/330,1450/330,1850/330,0/1000\nstutter = 380+420\n"),
+ array ( "name" => "Australia",  "iso" => "au", "conf" => "ringcadence = 400,200,400,2000\ndial = 413+438\nbusy = 425/375,0/375\nring = 413+438/400,0/200,413+438/400,0/2000\ncongestion = 425/375,0/375,420/375,0/375\ncallwaiting = 425/200,0/200,425/200,0/4400\ndialrecall = 413+438\nrecord = !425/1000,!0/15000,425/360,0/15000\ninfo = 425/2500,0/500\nstd = !525/100,!0/100,!525/100,!0/100,!525/100,!0/100,!525/100,!0/100,!525/100\nfacility = 425\nstutter = 413+438/100,0/40\nringmobile = 400+450/400,0/200,400+450/400,0/2000\n"),
+ array ( "name" => "Brazil",  "iso" => "br", "conf" => "ringcadence = 1000,4000\ndial = 425\nbusy = 425/250,0/250\nring = 425/1000,0/4000\ncongestion = 425/250,0/250,425/750,0/250\ncallwaiting = 425/50,0/1000\ndialrecall = 350+440\nrecord = 425/250,0/250\ninfo = 950/330,1400/330,1800/330\nstutter = 350+440\n"),
+ array ( "name" => "Belgium",  "iso" => "be", "conf" => "ringcadence = 1000,3000\ndial = 425\nbusy = 425/500,0/500\nring = 425/1000,0/3000\ncongestion = 425/167,0/167\ncallwaiting = 1400/175,0/175,1400/175,0/3500\ndialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440\nrecord = 1400/500,0/15000\ninfo = 900/330,1400/330,1800/330,0/1000\nstutter = 425/1000,0/250\n"),
+ array ( "name" => "Switzerland",  "iso" => "ch", "conf" => "ringcadence = 1000,4000\ndial = 425\nbusy = 425/500,0/500\nring = 425/1000,0/4000\ncongestion = 425/200,0/200\ncallwaiting = 425/200,0/200,425/200,0/4000\ndialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425\nrecord = 1400/80,0/15000\ninfo = 950/330,1400/330,1800/330,0/1000\nstutter = 425+340/1100,0/1100\n"),
+ array ( "name" => "Chile",  "iso" => "cl", "conf" => "ringcadence = 1000,3000\ndial = 400\nbusy = 400/500,0/500\nring = 400/1000,0/3000\ncongestion = 400/200,0/200\ncallwaiting = 400/250,0/8750\ndialrecall = !400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400\nrecord = 1400/500,0/15000\ninfo = 950/333,1400/333,1800/333,0/1000\nstutter = !400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400\n"),
+ array ( "name" => "China",  "iso" => "cn", "conf" => "ringcadence = 1000,4000\ndial = 450\nbusy = 450/350,0/350\nring = 450/1000,0/4000\ncongestion = 450/700,0/700\ncallwaiting = 450/400,0/4000\ndialrecall = 450\nrecord = 950/400,0/10000\ninfo = 450/100,0/100,450/100,0/100,450/100,0/100,450/400,0/400\nstutter = 450+425\n"),
+ array ( "name" => "Czech Republic",  "iso" => "cz", "conf" => "ringcadence = 1000,4000\ndial = 425/330,0/330,425/660,0/660\nbusy = 425/330,0/330\nring = 425/1000,0/4000\ncongestion = 425/165,0/165\ncallwaiting = 425/330,0/9000\ndialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425/330,0/330,425/660,0/660\nrecord = 1400/500,0/14000\ninfo = 950/330,0/30,1400/330,0/30,1800/330,0/1000\nstutter = 425/450,0/50\n"),
+ array ( "name" => "Germany",  "iso" => "de", "conf" => "ringcadence = 1000,4000\ndial = 425\nbusy = 425/480,0/480\nring = 425/1000,0/4000\ncongestion = 425/240,0/240\ncallwaiting = !425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,0\ndialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425\nrecord = 1400/80,0/15000\ninfo = 950/330,1400/330,1800/330,0/1000\nstutter = 425+400\n"),
+ array ( "name" => "Denmark",  "iso" => "dk", "conf" => "ringcadence = 1000,4000\ndial = 425\nbusy = 425/500,0/500\nring = 425/1000,0/4000\ncongestion = 425/200,0/200\ncallwaiting = !425/200,!0/600,!425/200,!0/3000,!425/200,!0/200,!425/200,0\ndialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425\nrecord = 1400/80,0/15000\ninfo = 950/330,1400/330,1800/330,0/1000\nstutter = 425/450,0/50\n"),
+ array ( "name" => "Estonia",  "iso" => "ee", "conf" => "ringcadence = 1000,4000\ndial = 425\nbusy = 425/300,0/300\nring = 425/1000,0/4000\ncongestion = 425/200,0/200\ncallwaiting = 950/650,0/325,950/325,0/30,1400/1300,0/2600\ndialrecall = 425/650,0/25\nrecord = 1400/500,0/15000\ninfo = 950/650,0/325,950/325,0/30,1400/1300,0/2600\nstutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425\n"),
+ array ( "name" => "Spain",  "iso" => "es", "conf" => "ringcadence = 1500,3000\ndial = 425\nbusy = 425/200,0/200\nring = 425/1500,0/3000\ncongestion = 425/200,0/200,425/200,0/200,425/200,0/600\ncallwaiting = 425/175,0/175,425/175,0/3500\ndialrecall = !425/200,!0/200,!425/200,!0/200,!425/200,!0/200,425\nrecord = 1400/500,0/15000\ninfo = 950/330,0/1000\ndialout = 500\n\n"),
+ array ( "name" => "Finland",  "iso" => "fi", "conf" => "ringcadence = 1000,4000\ndial = 425\nbusy = 425/300,0/300\nring = 425/1000,0/4000\ncongestion = 425/200,0/200\ncallwaiting = 425/150,0/150,425/150,0/8000\ndialrecall = 425/650,0/25\nrecord = 1400/500,0/15000\ninfo = 950/650,0/325,950/325,0/30,1400/1300,0/2600\nstutter = 425/650,0/25\n"),
+ array ( "name" => "France",  "iso" => "fr", "conf" => "ringcadence = 1500,3500\ndial = 440\nbusy = 440/500,0/500\nring = 440/1500,0/3500\ncongestion = 440/250,0/250\ncallwait = 440/300,0/10000\ndialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440\nrecord = 1400/500,0/15000\ninfo = !950/330,!1400/330,!1800/330\nstutter = !440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,440\n"),
+ array ( "name" => "Greece",  "iso" => "gr", "conf" => "ringcadence = 1000,4000\ndial = 425/200,0/300,425/700,0/800\nbusy = 425/300,0/300\nring = 425/1000,0/4000\ncongestion = 425/200,0/200\ncallwaiting = 425/150,0/150,425/150,0/8000\ndialrecall = 425/650,0/25\nrecord = 1400/400,0/15000\ninfo = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0\nstutter = 425/650,0/25\n"),
+ array ( "name" => "Hungary",  "iso" => "hu", "conf" => "ringcadence = 1250,3750\ndial = 425\nbusy = 425/300,0/300\nring = 425/1250,0/3750\ncongestion = 425/300,0/300\ncallwaiting = 425/40,0/1960\ndialrecall = 425+450\nrecord = 1400/400,0/15000\ninfo = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0\nstutter = 350+375+400\n"),
+ array ( "name" => "India",  "iso" => "in", "conf" => "ringcadence = 400,200,400,2000\ndial = 400*25\nbusy = 400/750,0/750\nring = 400*25/400,0/200,400*25/400,0/2000\ncongestion = 400/250,0/250\ncallwaiting = 400/200,0/100,400/200,0/7500\ndialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440\nrecord = 1400/500,0/15000\ninfo = !950/330,!1400/330,!1800/330,0/1000\nstutter = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440\n"),
+ array ( "name" => "Israel",  "iso" => "il", "conf" => "ringcadence = 1000,3000\ndial = 414\nbusy = 414/500,0/500\nring = 414/1000,0/3000\ncongestion = 414/250,0/250\ncallwaiting = 414/100,0/100,414/100,0/100,414/600,0/3000 \ndialrecall = !414/100,!0/100,!414/100,!0/100,!414/100,!0/100,414\nrecord = 1400/500,0/15000\ninfo = 1000/330,1400/330,1800/330,0/1000\nstutter = !414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,414 \n"),
+ array ( "name" => "Italy",  "iso" => "it", "conf" => "ringcadence = 1000,4000\ndial = 425/200,0/200,425/600,0/1000\nbusy = 425/500,0/500\nring = 425/1000,0/4000\ncongestion = 425/200,0/200\ncallwaiting = 425/400,0/100,425/250,0/100,425/150,0/14000\ndialrecall = 470/400,425/400\nrecord = 1400/400,0/15000\ninfo = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0\nstutter = 470/400,425/400\n"),
+ array ( "name" => "Lithuania",  "iso" => "lt", "conf" => "ringcadence = 1000,4000\ndial = 425\nbusy = 425/350,0/350\nring = 425/1000,0/4000\ncongestion = 425/200,0/200\ncallwaiting = 425/150,0/150,425/150,0/4000\ndialrecall = 425/500,0/50\nrecord = 1400/500,0/15000\ninfo = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0\nstutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425\n"),
+ array ( "name" => "Mexico",  "iso" => "mx", "conf" => "ringcadence = 2000,4000\ndial = 425\nbusy = 425/250,0/250\nring = 425/1000,0/4000\ncongestion = 425/250,0/250\ncallwaiting = 425/200,0/600,425/200,0/10000\ndialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440\nrecord = 1400/500,0/15000\ninfo = 950/330,0/30,1400/330,0/30,1800/330,0/1000\nstutter = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440\n"),
+ array ( "name" => "Netherlands",  "iso" => "nl", "conf" => "ringcadence = 1000,4000\ndial = 425\nbusy = 425/500,0/500\nring = 425/1000,0/4000\ncongestion = 425/250,0/250\ncallwaiting = 425/500,0/9500\ndialrecall = 425/500,0/50\nrecord = 1400/500,0/15000\ninfo = 950/330,1400/330,1800/330,0/1000\nstutter = 425/500,0/50\n"),
+ array ( "name" => "Norway",  "iso" => "no", "conf" => "ringcadence = 1000,4000\ndial = 425\nbusy = 425/500,0/500\nring = 425/1000,0/4000\ncongestion = 425/200,0/200\ncallwaiting = 425/200,0/600,425/200,0/10000\ndialrecall = 470/400,425/400\nrecord = 1400/400,0/15000\ninfo = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0\nstutter = 470/400,425/400\n"),
+ array ( "name" => "New Zealand",  "iso" => "nz", "conf" => "ringcadence = 400,200,400,2000\ndial = 400\nbusy = 400/250,0/250\nring = 400+450/400,0/200,400+450/400,0/2000\ncongestion = 400/375,0/375\ncallwaiting = !400/200,!0/3000,!400/200,!0/3000,!400/200,!0/3000,!400/200\ndialrecall = !400/100!0/100,!400/100,!0/100,!400/100,!0/100,400\nrecord = 1400/425,0/15000\ninfo = 400/750,0/100,400/750,0/100,400/750,0/100,400/750,0/400\nstutter = !400/100!0/100,!400/100,!0/100,!400/100,!0/100,!400/100!0/100,!400/100,!0/100,!400/100,!0/100,400\n"),
+ array ( "name" => "Poland",  "iso" => "pl", "conf" => "ringcadence = 1000,4000\ndial = 425\nbusy = 425/500,0/500\nring = 425/1000,0/4000\ncongestion = 425/500,0/500\ncallwaiting = 425/150,0/150,425/150,0/4000\ndialrecall = 425/500,0/50\nrecord = 1400/500,0/15000\ninfo = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000\nstutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425\n"),
+ array ( "name" => "Portugal",  "iso" => "pt", "conf" => "ringcadence = 1000,5000\ndial = 425\nbusy = 425/500,0/500\nring = 425/1000,0/5000\ncongestion = 425/200,0/200\ncallwaiting = 440/300,0/10000\ndialrecall = 425/1000,0/200\nrecord = 1400/500,0/15000\ninfo = 950/330,1400/330,1800/330,0/1000\nstutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425\n"),
+ array ( "name" => "Russia / ex Soviet Union",  "iso" => "ru", "conf" => "ringcadence = 800,3200\ndial = 425\nbusy = 425/350,0/350\nring = 425/800,0/3200\ncongestion = 425/350,0/350\ncallwaiting = 425/200,0/5000\ndialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440\nrecord = 1400/500,0/15000\ninfo = !950/330,!1400/330,!1800/330,0\n"),
+ array ( "name" => "Singapore",  "iso" => "sg", "conf" => "ringcadence = 400,200,400,2000\ndial = 425\nring = 425*24/400,0/200,425*24/400,0/2000 ; modulation should be 100%, not 90%\nbusy = 425/750,0/750\ncongestion = 425/250,0/250\ncallwaiting = 425*24/300,0/200,425*24/300,0/3200\nstutter = !425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,425\ninfo = 950/330,1400/330,1800/330,0/1000 ; not currently in use acc. to reference\ndialrecall = 425*24/500,0/500,425/500,0/2500 ; unspecified in IDA reference, use repeating Holding Tone A,B\nrecord = 1400/500,0/15000 ; unspecified in IDA reference, use 0.5s tone every 15s\nnutone = 425/2500,0/500\nintrusion = 425/250,0/2000\nwarning = 425/624,0/4376 ; end of period tone, warning\nacceptance = 425/125,0/125\nholdinga = !425*24/500,!0/500 ; followed by holdingb\nholdingb = !425/500,!0/2500\n"),
+ array ( "name" => "South Africa",  "iso" => "za", "conf" => "ringcadence = 400,200,400,2000\ndial = 400*33\nbusy = 400/500,0/500\nring = 400*33/400,0/200,400*33/400,0/2000\ncongestion = 400/250,0/250\ncallwaiting = 400*33/250,0/250,400*33/250,0/250,400*33/250,0/250,400*33/250,0/250\ndialrecall = 350+440\nrecord = 1400/500,0/10000\ninfo = 950/330,1400/330,1800/330,0/330\nstutter =!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,400*33 \n"),
+ array ( "name" => "Sweden",  "iso" => "se", "conf" => "ringcadence = 1000,5000\ndial = 425\nbusy = 425/250,0/250\nring = 425/1000,0/5000\ncongestion = 425/250,0/750\ncallwaiting = 425/200,0/500,425/200,0/9100\ndialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425\nrecord = 1400/500,0/15000\ninfo = !950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024,!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024,!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024,!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024,!950/332,!0/24,!1400/332,!0/24,!1800/332,0\nstutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425\n"),
+ array ( "name" => "United Kingdom",  "iso" => "uk", "conf" => "ringcadence = 400,200,400,2000\ndial = 350+440\nspecialdial = 350+440/750,440/750\nbusy = 400/375,0/375\ncongestion = 400/400,0/350,400/225,0/525\nspecialcongestion = 400/200,1004/300\nunobtainable = 400\nring = 400+450/400,0/200,400+450/400,0/2000\ncallwaiting = 400/100,0/4000\nspecialcallwaiting = 400/250,0/250,400/250,0/250,400/250,0/5000\ncreditexpired = 400/125,0/125\nconfirm = 1400\nswitching = 400/200,0/400,400/2000,0/400\ninfo = 950/330,0/15,1400/330,0/15,1800/330,0/1000\nrecord = 1400/500,0/60000\nstutter = 350+440/750,440/750\n"),
+ array ( "name" => "United States / North America",  "iso" => "us", "conf" => "ringcadence = 2000,4000\ndial = 350+440\nbusy = 480+620/500,0/500\nring = 440+480/2000,0/4000\ncongestion = 480+620/250,0/250\ncallwaiting = 440/300,0/10000\ndialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440\nrecord = 1400/500,0/15000\ninfo = !950/330,!1400/330,!1800/330,0\nstutter = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440\n"),
+ array ( "name" => "United States Circa 1950/ North America",  "iso" => "us-old", "conf" => "ringcadence = 2000,4000\ndial = 600*120\nbusy = 500*100/500,0/500\nring = 420*40/2000,0/4000\ncongestion = 500*100/250,0/250\ncallwaiting = 440/300,0/10000\ndialrecall = !600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,600*120\nrecord = 1400/500,0/15000\ninfo = !950/330,!1400/330,!1800/330,0\nstutter = !600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,600*120\n"),
+ array ( "name" => "Taiwan",  "iso" => "tw", "conf" => "ringcadence = 1000,4000\ndial = 350+440\nbusy = 480+620/500,0/500\nring = 440+480/1000,0/2000\ncongestion = 480+620/250,0/250\ncallwaiting = 350+440/250,0/250,350+440/250,0/3250\ndialrecall = 300/1500,0/500\nrecord = 1400/500,0/15000\ninfo = !950/330,!1400/330,!1800/330,0\nstutter = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440\n"),
+ array ( "name" => "Venezuela / South America",  "iso" => "ve", "conf" => "; Tone definition source for ve found on\n; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf\nringcadence = 1000,4000\ndial = 425\nbusy = 425/500,0/500\nring = 425/1000,0/4000\ncongestion = 425/250,0/250\ncallwaiting = 400+450/300,0/6000\ndialrecall = 425\nrecord =  1400/500,0/15000\ninfo = !950/330,!1440/330,!1800/330,0/1000\n"),);
+}
+
+function general_display_zones($curzone) {
+	$zonelist = general_get_zonelist();
+	echo "<select name='TONEZONE'>\n";
+	foreach ($zonelist as $zone) {
+		if ($zone['iso'] == $curzone) 
+			echo "<option selected value='{$zone['iso']}'>{$zone['name']}</option>\n";
+		else	
+			echo "<option value='{$zone['iso']}'>{$zone['name']}</option>\n";
+	}
+	echo "</select>";
+	
+}
+
+function general_generate_indications() {
+	global $db;
+	global $asterisk_conf;
+
+	$sql = "SELECT value FROM globals WHERE variable='TONEZONE'";
+	$result = $db->getRow($sql,DB_FETCHMODE_ASSOC);
+
+	$filename = isset($asterisk_conf["astetcdir"]) && $asterisk_conf["astetcdir"] != '' ? rtrim($asterisk_conf["astetcdir"],DIRECTORY_SEPARATOR) : "/etc/asterisk";
+	$filename .= "/indications.conf";
+	$fd = fopen($filename, "w");
+	fwrite($fd, "[general]\ncountry=".$result['value']."\n\n");
+
+	$zonelist = general_get_zonelist();
+	foreach ($zonelist as $zone) {
+		fwrite($fd, "[{$zone['iso']}]\n{$zone['conf']}\n\n");
+	}
+	fclose($fd);
+}
+/* end page.routing.php functions */
+
+
+
+// init registered 'your' config load and config process functions
+function core_users_configpageinit($dispnum) {
+	global $currentcomponent;
+	global $amp_conf;
+
+	if ( $dispnum == 'users' || $dispnum == 'extensions' ) {
+		// Setup option list we need
+		$currentcomponent->addoptlistitem('recordoptions', 'Adhoc', _("On Demand"));
+		$currentcomponent->addoptlistitem('recordoptions', 'Always', _("Always"));
+		$currentcomponent->addoptlistitem('recordoptions', 'Never', _("Never"));
+		$currentcomponent->setoptlistopts('recordoptions', 'sort', false);
+
+		$currentcomponent->addoptlistitem('faxdetecttype', '0', _("None"));
+		$currentcomponent->addoptlistitem('faxdetecttype', '1', 'Zaptel');
+		$currentcomponent->addoptlistitem('faxdetecttype', '2', 'NVFax');
+		$currentcomponent->setoptlistopts('faxdetecttype', 'sort', false);
+
+		$currentcomponent->addoptlistitem('privyn', '0', _("No"));
+		$currentcomponent->addoptlistitem('privyn', '1', _("Yes"));
+		$currentcomponent->setoptlistopts('privyn', 'sort', false);
+
+		$currentcomponent->addoptlistitem('callwaiting', 'enabled', _("Enable"));
+		$currentcomponent->addoptlistitem('callwaiting', 'disabled', _("Disable"));
+		$currentcomponent->setoptlistopts('callwaiting', 'sort', false);
+
+		$currentcomponent->addoptlistitem('ringtime', '0', 'Default');
+		for ($i=1; $i <= 120; $i++) {
+			$currentcomponent->addoptlistitem('ringtime', "$i", "$i");
+		}
+		$currentcomponent->setoptlistopts('ringtime', 'sort', false);
+
+		$currentcomponent->addoptlistitem('faxdestoptions', 'default', _("FreePBX default"));
+		$currentcomponent->addoptlistitem('faxdestoptions', 'disabled', _("disabled"));
+		$currentcomponent->addoptlistitem('faxdestoptions', 'system', _("system"));
+		$currentcomponent->setoptlistopts('faxdestoptions', 'sort', false);
+
+		if (function_exists('music_list')) {
+				$tresults = music_list($amp_conf['ASTVARLIBDIR']."/mohmp3");
+		    if (isset($tresults[0])) {
+			foreach ($tresults as $tresult) {
+			    $currentcomponent->addoptlistitem('mohclass', $tresult, $tresult);
+			}
+		    $currentcomponent->setoptlistopts('mohclass', 'sort', false);
+		    }
+		}
+
+		//get unique devices to finishoff faxdestoptions list
+		$devices = core_devices_list();
+		if (isset($devices)) {
+			foreach ($devices as $device) {
+				$currentcomponent->addoptlistitem('faxdestoptions', $device[0], "$device[1] <$device[0]>");
+			}
+		}
+
+		// Add the 'proces' functions
+		$currentcomponent->addguifunc('core_users_configpageload');
+		// Ensure users is called in middle order ($sortorder = 5), this is to allow
+		// other modules to call stuff before / after the processing of users if needed
+		// e.g. Voicemail module needs to create mailbox BEFORE the users as the mailbox
+		// context is needed by the add users function
+		$currentcomponent->addprocessfunc('core_users_configprocess', 5);			
+	}
+}
+
+function core_users_configpageload() {
+	global $currentcomponent;
+	global $amp_conf;
+
+	// Ensure variables possibly extracted later exist
+	$name = $directdid = $didalert = $outboundcid = $answer = null;
+	$record_in = $record_out = $faxexten = $faxemail = $mohclass = $sipname = $cid_masquerade = null;
+
+	// Init vars from $_REQUEST[]
+	$display = isset($_REQUEST['display'])?$_REQUEST['display']:null;;
+	$action = isset($_REQUEST['action'])?$_REQUEST['action']:null;
+	$extdisplay = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:null;
+	$tech_hardware = isset($_REQUEST['tech_hardware'])?$_REQUEST['tech_hardware']:null;
+
+	if ( $action == 'del' ) { // Deleted
+
+		$currentcomponent->addguielem('_top', new gui_subheading('del', $extdisplay.' '._("deleted"), false));
+
+	} elseif ( $display == 'extensions' && ($extdisplay == '' && $tech_hardware == '') ) { // Adding
+
+		// do nothing as you want the Devices to handle this bit
+
+	} else {
+
+		$delURL = $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'].'&action=del';
+	
+		if ( is_string($extdisplay) ) {	
+			$extenInfo=core_users_get($extdisplay);
+			extract($extenInfo);
+			if (isset($deviceInfo) && is_array($deviceInfo))
+				extract($deviceInfo);
+	
+			if ( $display == 'extensions' ) {
+				$currentcomponent->addguielem('_top', new gui_pageheading('title', _("Extension").": $extdisplay", false), 0);
+				$currentcomponent->addguielem('_top', new gui_link('del', _("Delete Extension")." $extdisplay", $delURL, true, false), 0);
+			} else {
+				$currentcomponent->addguielem('_top', new gui_pageheading('title', _("User").": $extdisplay", false), 0);
+				$currentcomponent->addguielem('_top', new gui_link('del', _("Delete User")." $extdisplay", $delURL, true, false), 0);
+			}
+
+		} elseif ( $display != 'extensions' ) {
+			$currentcomponent->addguielem('_top', new gui_pageheading('title', _("Add User/Extension")), 0);
+		}
+		
+		// Setup vars for use in the gui later on							
+		$fc_logon = featurecodes_getFeatureCode('core', 'userlogon');
+		$fc_logoff = featurecodes_getFeatureCode('core', 'userlogoff');
+		
+		$msgInvalidExtNum = _("Please enter a valid extension number.");
+		$msgInvalidCidNum = _("Please enter a valid CID Num Alias (must be a valid number).");
+		$msgInvalidExtPwd = _("Please enter valid User Password using numbers only");
+		$msgInvalidDispName = _("Please enter a valid Display Name");
+		$msgInvalidOutboundCID = _("Please enter a valid Outbound CID");
+		$msgInvalidPause = _("Please enter a valid pause time in seconds, using digits only");
+
+		// This is the actual gui stuff
+		$currentcomponent->addguielem('_top', new gui_hidden('action', ($extdisplay ? 'edit' : 'add')));
+		$currentcomponent->addguielem('_top', new gui_hidden('extdisplay', $extdisplay));
+		
+		if ( $display == 'extensions' ) {
+			$section = ($extdisplay ? _("Edit Extension") : _("Add Extension"));			
+		} else {
+			$section = ($extdisplay ? _("Edit User") : _("Add User"));
+		}
+		if ( $extdisplay ) {
+			$currentcomponent->addguielem($section, new gui_hidden('extension', $extdisplay), 2);
+		} else {
+			$currentcomponent->addguielem($section, new gui_textbox('extension', $extdisplay, 'User Extension', 'The extension number to dial to reach this user.', '!isInteger()', $msgInvalidExtNum, false), 3);
+		}
+		if ( $display != 'extensions' ) {
+			$currentcomponent->addguielem($section, new gui_password('password', $password, 'User Password', _("A user will enter this password when logging onto a device.").' '.$fc_logon.' '._("logs into a device.").' '.$fc_logoff.' '._("logs out of a device."), '!isInteger() && !isWhitespace()', $msgInvalidExtPwd, true));
+			// extra JS function check required for blank password warning -- call last in the onsubmit() function
+			$currentcomponent->addjsfunc('onsubmit()', "\treturn checkBlankUserPwd();\n", 9);
+		}
+		$currentcomponent->addguielem($section, new gui_textbox('name', $name, 'Display Name', 'The caller id name for calls from this user will be set to this name. Only enter the name, NOT the number.', '!isCallerID()', $msgInvalidDispName, false));
+		$cid_masquerade = (trim($cid_masquerade) == $extdisplay)?"":$cid_masquerade;
+		$currentcomponent->addguielem($section, new gui_textbox('cid_masquerade', $cid_masquerade, 'CID Num Alias', 'The CID Number to use for internal calls, if different from the extension number. This is used to masquerade as a different user. A common example is a team of support people who would like their internal callerid to display the general support number (a ringgroup or queue). There will be no effect on external calls.', '!isWhitespace() && !isInteger()', $msgInvalidCidNum, false));
+		$currentcomponent->addguielem($section, new gui_textbox('sipname', $sipname, 'SIP Alias', "If you want to support direct sip dialing of users internally or through anonymous sip calls, you can supply a friendly name that can be used in addition to the users extension to call them."));
+		
+		$section = 'Extension Options';
+		$currentcomponent->addguielem($section, new gui_textbox('directdid', $directdid, 'Direct DID', "The direct DID that is associated with this extension. The DID should be in the same format as provided by the provider (e.g. full number, 4 digits for 10x4, etc).<br><br>Format should be: <b>XXXXXXXXXX</b><br><br>Leave this field blank to disable the direct DID feature for this extension. All non-numeric characters will be stripped."), 3);
+		$currentcomponent->addguielem($section, new gui_textbox('didalert', $didalert, 'DID Alert Info', "Alert Info can be used for distinctive ring on SIP phones. Set this value to the desired Alert Info to be sent to the phone when this DID is called. Leave blank to use default values. Will have no effect if no Direct DID is set"));
+		if (function_exists('music_list')) {
+		    $currentcomponent->addguielem($section, new gui_selectbox('mohclass', $currentcomponent->getoptlist('mohclass'), $mohclass, 'Music on Hold', "Set the MoH class that will be used for calls that come in on this Direct DID. For example, choose a type appropriate for a originating country which may have announcements in their language. Only effects MoH class when the call came in from the Direct DID.", false));
+		}
+		$currentcomponent->addguielem($section, new gui_textbox('outboundcid', $outboundcid, 'Outbound CID', "Overrides the caller id when dialing out a trunk. Any setting here will override the common outbound caller id set in the Trunks admin.<br><br>Format: <b>\"caller name\" &lt;#######&gt;</b><br><br>Leave this field blank to disable the outbound callerid feature for this user.", '!isCallerID()', $msgInvalidOutboundCID, true));
+		$ringtimer = (isset($ringtimer) ? $ringtimer : '0');
+		$currentcomponent->addguielem($section, new gui_selectbox('ringtimer', $currentcomponent->getoptlist('ringtime'), $ringtimer, 'Ring Time', "Number of seconds to ring prior to going to voicemail. Default will use the value set in the General Tab. If no voicemail is configured this will be ignored.", false));
+		if (!isset($callwaiting)) {
+			if ($amp_conf['ENABLECW']) {
+				$callwaiting = 'enabled';
+			} else {
+				$callwaiting = 'disabled';
+			}
+		}
+		$currentcomponent->addguielem($section, new gui_selectbox('callwaiting', $currentcomponent->getoptlist('callwaiting'), $callwaiting, 'Call Waiting', "Set the initial/current Call Waiting state for this user's extension", false));
+
+		$section = 'Recording Options';
+		$currentcomponent->addguielem($section, new gui_selectbox('record_in', $currentcomponent->getoptlist('recordoptions'), $record_in, 'Record Incoming', "Record all inbound calls received at this extension.", false));
+		$currentcomponent->addguielem($section, new gui_selectbox('record_out', $currentcomponent->getoptlist('recordoptions'), $record_out, 'Record Outgoing', "Record all outbound calls received at this extension.", false));
+
+		$section = 'Fax Handling';
+		$wait = (isset($wait) ? $wait : '0');
+		$currentcomponent->addguielem($section, new gui_selectbox('faxexten', $currentcomponent->getoptlist('faxdestoptions'), $faxexten, 'Fax Extension', "Select 'system' to have the system receive and email faxes.<br><br>The FreePBX default is defined in General Settings.", false), 4);
+		$currentcomponent->addguielem($section, new gui_textbox('faxemail', $faxemail, 'Fax Email', "Email address is used if 'system' has been chosen for the fax extension above.<br><br>Leave this blank to use the FreePBX default in General Settings"));
+		$currentcomponent->addguielem($section, new gui_selectbox('answer', $currentcomponent->getoptlist('faxdetecttype'), $answer, 'Fax Detection Type', "Selecting Zaptel or NVFax will immediately answer the call and play ringing tones to the caller for the number of seconds in Pause below. Use NVFax on SIP or IAX trunks.", false));
+		$currentcomponent->addguielem($section, new gui_textbox('wait', $wait, 'Pause after answer', 'The number of seconds we should wait after performing an Immediate Answer. The primary purpose of this is to pause and listen for a fax tone before allowing the call to proceed.', '!isInteger()', $msgInvalidPause, false));
+
+		$section = 'Privacy';
+		$privacyman = (isset($privacyman) ? $privacyman : '0');
+		$currentcomponent->addguielem($section, new gui_selectbox('privacyman', $currentcomponent->getoptlist('privyn'), $privacyman, 'Privacy Manager', "If no Caller ID is sent, Privacy Manager will asks the caller to enter their 10 digit phone number. The caller is given 3 attempts.", false), 4);
+
+	}
+}
+
+function core_users_configprocess() {
+	if ( !class_exists('agi_asteriskmanager') )
+		include 'common/php-asmanager.php';
+	
+	//create vars from the request
+	extract($_REQUEST);
+	
+	//make sure we can connect to Asterisk Manager
+	if (!checkAstMan()) {
+		return false;
+	}
+
+	//check if the extension is within range for this user
+	if (isset($extension) && !checkRange($extension)){
+		echo "<script>javascript:alert('". _("Warning! Extension")." ".$extension." "._("is not allowed for your account").".');</script>";
+		$GLOBALS['abort'] = true;
+	} else {
+		//if submitting form, update database
+		if (!isset($action)) $action = null;
+		switch ($action) {
+			case "add":
+				if (core_users_add($_REQUEST)) {
+					needreload();
+					redirect_standard_continue();
+				} else {
+					// really bad hack - but if core_users_add fails, want to stop core_devices_add
+					$GLOBALS['abort'] = true;
+				}
+			break;
+			case "del":
+				core_users_del($extdisplay);
+				core_users_cleanastdb($extdisplay);
+				if (function_exists('findmefollow_del')) {
+				    findmefollow_del($extdisplay);
+				}
+				needreload();
+				redirect_standard_continue();
+			break;
+			case "edit":
+				if (core_users_edit($extdisplay,$_REQUEST)) {
+					needreload();
+					redirect_standard_continue('extdisplay');
+				} else {
+					// really bad hack - but if core_users_edit fails, want to stop core_devices_edit
+					$GLOBALS['abort'] = true;
+				}
+			break;
+		}
+	}
+	return true;
+}
+
+
+function core_devices_configpageinit($dispnum) {
+	global $currentcomponent;
+
+	if ( $dispnum == 'devices' || $dispnum == 'extensions' ) {
+		// Setup arrays for device types
+		$currentcomponent->addgeneralarray('devtechs');
+		
+		// Some errors for the validation bits
+		$msgInvalidDTMFMODE = _("Please enter the dtmfmode for this device");
+		$msgInvalidChannel = _("Please enter the channel for this device");
+		$msgConfirmSecret = _("You have not entered a Secret for this device, although this is possible it is generally bad practice to not assign a Secret to a device. Are you sure you want to leave the Secret empty?");
+		$msgInvalidSecret = _("Please enter a Secret for this device");
+		
+		// zap
+		$tmparr = array();
+		$tmparr['channel'] = array('value' => '', 'level' => 0, 'jsvalidation' => 'isEmpty()', 'failvalidationmsg' => $msgInvalidChannel);
+		$tmparr['context'] = array('value' => 'from-internal', 'level' => 1);
+		$tmparr['immediate'] = array('value' => 'no', 'level' => 1);
+		$tmparr['signalling'] = array('value' => 'fxo_ks', 'level' => 1);
+		$tmparr['echocancel'] = array('value' => 'yes', 'level' => 1);
+		$tmparr['echocancelwhenbridged'] = array('value' => 'no', 'level' => 1);
+		$tmparr['echotraining'] = array('value' => '800', 'level' => 1);
+		$tmparr['busydetect'] = array('value' => 'no', 'level' => 1);
+		$tmparr['busycount'] = array('value' => '7', 'level' => 1);
+		$tmparr['callprogress'] = array('value' => 'no', 'level' => 1);
+		$tmparr['dial'] = array('value' => '', 'level' => 1);
+		$tmparr['accountcode'] = array('value' => '', 'level' => 1);
+		$tmparr['mailbox'] = array('value' => '', 'level' => 1);
+		$currentcomponent->addgeneralarrayitem('devtechs', 'zap', $tmparr);
+		unset($tmparr);
+		
+		// iax2
+		$tmparr = array();
+		$tmparr['secret'] = array('value' => '', 'level' => 0, 'jsvalidation' => 'isEmpty() && !confirm("'.$msgConfirmSecret.'")', 'failvalidationmsg' => $msgInvalidSecret);
+		$tmparr['notransfer'] = array('value' => 'yes', 'level' => 1);
+		$tmparr['context'] = array('value' => 'from-internal', 'level' => 1);
+		$tmparr['host'] = array('value' => 'dynamic', 'level' => 1);
+		$tmparr['type'] = array('value' => 'friend', 'level' => 1);
+		$tmparr['port'] = array('value' => '4569', 'level' => 1);
+		$tmparr['qualify'] = array('value' => 'yes', 'level' => 1);
+		$tmparr['disallow'] = array('value' => '', 'level' => 1);
+		$tmparr['allow'] = array('value' => '', 'level' => 1);
+		$tmparr['dial'] = array('value' => '', 'level' => 1);
+		$tmparr['accountcode'] = array('value' => '', 'level' => 1);
+		$tmparr['mailbox'] = array('value' => '', 'level' => 1);
+		$currentcomponent->addgeneralarrayitem('devtechs', 'iax2', $tmparr);
+		unset($tmparr);
+
+		// sip
+		$tmparr = array();
+		$tmparr['secret'] = array('value' => '', 'level' => 0, 'jsvalidation' => 'isEmpty() && !confirm("'.$msgConfirmSecret.'")', 'failvalidationmsg' => $msgInvalidSecret);
+		$tmparr['dtmfmode'] = array('value' => 'rfc2833', 'level' => 0, 'jsvalidation' => 'isEmpty()', 'failvalidationmsg' => $msgInvalidDTMFMODE );
+		$tmparr['canreinvite'] = array('value' => 'no', 'level' => 1);
+		$tmparr['context'] = array('value' => 'from-internal', 'level' => 1);
+		$tmparr['host'] = array('value' => 'dynamic', 'level' => 1);
+		$tmparr['type'] = array('value' => 'friend', 'level' => 1);
+		$tmparr['nat'] = array('value' => 'yes', 'level' => 1);
+		$tmparr['port'] = array('value' => '5060', 'level' => 1);
+		$tmparr['qualify'] = array('value' => 'yes', 'level' => 1);
+		$tmparr['callgroup'] = array('value' => '', 'level' => 1);
+		$tmparr['pickupgroup'] = array('value' => '', 'level' => 1);
+		$tmparr['disallow'] = array('value' => '', 'level' => 1);
+		$tmparr['allow'] = array('value' => '', 'level' => 1);
+		$tmparr['dial'] = array('value' => '', 'level' => 1);
+		$tmparr['accountcode'] = array('value' => '', 'level' => 1);
+		$tmparr['mailbox'] = array('value' => '', 'level' => 1);
+		$currentcomponent->addgeneralarrayitem('devtechs', 'sip', $tmparr);
+		unset($tmparr);
+
+		// custom
+		$tmparr = array();
+		$tmparr['dial'] = array('value' => '', 'level' => 0);
+		$currentcomponent->addgeneralarrayitem('devtechs', 'custom', $tmparr);
+		unset($tmparr);
+		
+		// Devices list
+		$currentcomponent->addoptlistitem('devicelist', 'sip_generic', _("Generic SIP Device"));
+		$currentcomponent->addoptlistitem('devicelist', 'iax2_generic', _("Generic IAX2 Device"));
+		$currentcomponent->addoptlistitem('devicelist', 'zap_generic', _("Generic ZAP Device"));
+		$currentcomponent->addoptlistitem('devicelist', 'custom_custom', _("Other (Custom) Device"));
+		$currentcomponent->setoptlistopts('devicelist', 'sort', false);
+
+
+		// Option lists used by the gui
+		$currentcomponent->addoptlistitem('devicetypelist', 'fixed', _("Fixed"));
+		$currentcomponent->addoptlistitem('devicetypelist', 'adhoc', _("Adhoc"));
+		$currentcomponent->setoptlistopts('devicetypelist', 'sort', false);
+		
+		$currentcomponent->addoptlistitem('deviceuserlist', 'none', _("none"));
+		$currentcomponent->addoptlistitem('deviceuserlist', 'new', _("New User"));
+		$users = core_users_list();
+		if (isset($users)) {
+			foreach ($users as $auser) {
+				$currentcomponent->addoptlistitem('deviceuserlist', $auser[0], $auser[0]);
+			}
+		}
+		$currentcomponent->setoptlistopts('deviceuserlist', 'sort', false);
+
+		// Add the 'proces' functions
+		$currentcomponent->addguifunc('core_devices_configpageload');
+		$currentcomponent->addprocessfunc('core_devices_configprocess');
+	}
+}
+
+function core_devices_configpageload() {
+	global $currentcomponent;
+
+	// Init vars from $_REQUEST[]
+	$display = isset($_REQUEST['display'])?$_REQUEST['display']:null;;
+	$action = isset($_REQUEST['action'])?$_REQUEST['action']:null;
+	$extdisplay = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:null;
+	$tech_hardware = isset($_REQUEST['tech_hardware'])?$_REQUEST['tech_hardware']:null;
+	
+	if ( $action == 'del' ) { // Deleted
+
+		if ( $display != 'extensions' )
+			$currentcomponent->addguielem('_top', new gui_subheading('del', $extdisplay.' '._("deleted"), false));
+
+	} elseif ( $extdisplay == '' && $tech_hardware == '' ) { // Adding
+
+		if ( $display != 'extensions') {
+			$currentcomponent->addguielem('_top', new gui_pageheading('title', _("Add Device")), 0);
+		} else {
+			$currentcomponent->addguielem('_top', new gui_pageheading('title', _("Add an Extension")), 0);
+		}
+		$currentcomponent->addguielem('_top', new gui_label('instructions', _("Please select your Device below then click Submit")));
+		$currentcomponent->addguielem('Device', new gui_selectbox('tech_hardware', $currentcomponent->getoptlist('devicelist'), '', 'Device', '', false));
+
+	} else {
+
+		$deviceInfo = array();
+		if ( $extdisplay ) { // Editing
+
+			$deviceInfo = core_devices_get($extdisplay);
+
+			if ( $display != 'extensions' ) {
+				$currentcomponent->addguielem('_top', new gui_pageheading('title', _("Device").": $extdisplay", false), 0);
+
+				$delURL = $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'].'&action=del';
+				$currentcomponent->addguielem('_top', new gui_link('del', _("Delete Device")." $extdisplay", $delURL, true, false), 0);
+			}
+	
+		} else {
+
+			$tmparr = explode('_', $tech_hardware);
+			$deviceInfo['tech'] = $tmparr[0];
+			$deviceInfo['hardware'] = $tmparr[1];
+			unset($tmparr);
+			
+			if ( $display != 'extensions' ) {
+				$currentcomponent->addguielem('_top', new gui_pageheading('title', _("Add").' '.strtoupper($deviceInfo['tech']).' '._("Device")), 0);
+			} else {
+				$currentcomponent->addguielem('_top', new gui_pageheading('title', _("Add").' '.strtoupper($deviceInfo['tech']).' '._("Extension")), 0);
+			}
+
+		}
+
+		// Ensure they exist before the extract
+		$devinfo_description = $devinfo_emergency_cid = null;
+		$devinfo_devicetype = $devinfo_user = $devinfo_hardware = null;
+		if ( is_array($deviceInfo) )
+			extract($deviceInfo, EXTR_PREFIX_ALL, 'devinfo');
+
+		// Setup vars for use in the gui later on							
+		$fc_logon = featurecodes_getFeatureCode('core', 'userlogon');
+		$fc_logoff = featurecodes_getFeatureCode('core', 'userlogoff');
+
+		$msgInvalidDevID = _("Please enter a device id.");
+		$msgInvalidDevDesc = _("Please enter a valid Description for this device");
+		$msgInvalidEmergCID = _("Please enter a valid Emergency CID");
+		$msgInvalidExtNum = _("Please enter a valid extension number.");
+		
+		// Actual gui
+		$currentcomponent->addguielem('_top', new gui_hidden('action', ($extdisplay ? 'edit' : 'add')));
+		$currentcomponent->addguielem('_top', new gui_hidden('extdisplay', $extdisplay));
+
+		if ( $display != 'extensions' ) {
+			$section = 'Device Info';
+			if ( $extdisplay ) { // Editing
+				$currentcomponent->addguielem($section, new gui_hidden('deviceid', $extdisplay));
+			} else { // Adding
+				$currentcomponent->addguielem($section, new gui_textbox('deviceid', $extdisplay, 'Device ID', 'Give your device a unique integer ID.  The device will use this ID to authenicate to the system.', '!isInteger()', $msgInvalidDevID, false));
+			}
+			$currentcomponent->addguielem($section, new gui_textbox('description', $devinfo_description, 'Description', 'The caller id name for this device will be set to this description until it is logged into.', '!isAlphanumeric() || isWhitespace()', $msgInvalidDevDesc, false));
+			$currentcomponent->addguielem($section, new gui_textbox('emergency_cid', $devinfo_emergency_cid, 'Emergency CID', 'This caller id will always be set when dialing out an Outbound Route flagged as Emergency.  The Emergency CID overrides all other caller id settings.', '!isCallerID()', $msgInvalidEmergCID));
+			$currentcomponent->addguielem($section, new gui_selectbox('devicetype', $currentcomponent->getoptlist('devicetypelist'), $devinfo_devicetype, 'Device Type', _("Devices can be fixed or adhoc. Fixed devices are always associated to the same extension/user. Adhoc devices can be logged into and logged out of by users.").' '.$fc_logon.' '._("logs into a device.").' '.$fc_logoff.' '._("logs out of a device."), false));
+			$currentcomponent->addguielem($section, new gui_selectbox('deviceuser', $currentcomponent->getoptlist('deviceuserlist'), $devinfo_user, 'Default User', 'Fixed devices will always mapped to this user.  Adhoc devices will be mapped to this user by default.<br><br>If selecting "New User", a new User Extension of the same Device ID will be set as the Default User.', false));
+		} else {
+			$section = 'Extension Options';
+			$currentcomponent->addguielem($section, new gui_textbox('emergency_cid', $devinfo_emergency_cid, 'Emergency CID', 'This caller id will always be set when dialing out an Outbound Route flagged as Emergency.  The Emergency CID overrides all other caller id settings.', '!isCallerID()', $msgInvalidEmergCID));
+		}
+		$currentcomponent->addguielem($section, new gui_hidden('tech', $devinfo_tech));
+		$currentcomponent->addguielem($section, new gui_hidden('hardware', $devinfo_hardware));
+
+		$section = 'Device Options';
+		$currentcomponent->addguielem($section, new gui_label('techlabel', sprintf(_("This device uses %s technology."),$devinfo_tech)),4);
+		$devopts = $currentcomponent->getgeneralarrayitem('devtechs', $devinfo_tech);
+		foreach ($devopts as $devopt=>$devoptarr) {
+			$devopname = 'devinfo_'.$devopt;
+			$devoptcurrent = isset($$devopname) ? $$devopname : $devoptarr['value'];
+			$devoptjs = isset($devoptarr['jsvalidation']) ? $devoptarr['jsvalidation'] : '';
+			$devoptfailmsg = isset($devoptarr['failvalidationmsg']) ? $devoptarr['failvalidationmsg'] : '';
+			
+			if ( $devoptarr['level'] == 0 || ($extdisplay && $devoptarr['level'] == 1) ) { // editing to show advanced as well
+				$currentcomponent->addguielem($section, new gui_textbox($devopname, $devoptcurrent, $devopt, '', $devoptjs, $devoptfailmsg), 4);
+			} else { // add so only basic
+				$currentcomponent->addguielem($section, new gui_hidden($devopname, $devoptcurrent), 4);
+			}
+		}
+	}
+}
+
+function core_devices_configprocess() {
+	if ( !class_exists('agi_asteriskmanager') )
+		include 'common/php-asmanager.php';
+
+	//make sure we can connect to Asterisk Manager
+	if (!checkAstMan()) {
+		return false;
+	}
+	
+	//create vars from the request
+	extract($_REQUEST);
+
+	$extension = isset($extension)?$extension:null;
+	$deviceid = isset($deviceid)?$deviceid:null;
+	$name = isset($name)?$name:null;
+	$action = isset($action)?$action:null;
+
+	// fixed users only in extensions mode
+	if ( $display == 'extensions' ) {
+		$devicetype = 'fixed';
+		$deviceid = $deviceuser = $extension;
+        $description = $name;
+	}
+	
+	//if submitting form, update database
+	switch ($action) {
+		case "add":
+		// really bad hack - but if core_users_add fails, want to stop core_devices_add
+		if (!isset($GLOBALS['abort']) || $GLOBALS['abort'] !== true) {
+			if (core_devices_add($deviceid,$tech,$devinfo_dial,$devicetype,$deviceuser,$description,$emergency_cid)) {
+				needreload();
+				if ($deviceuser != 'new') {
+					redirect_standard_continue();
+				}
+			}
+		}
+		break;
+		case "del":
+			core_devices_del($extdisplay);
+			needreload();
+			redirect_standard_continue();
+		break;
+		case "edit":  //just delete and re-add
+			// really bad hack - but if core_users_edit fails, want to stop core_devices_edit
+			if (!isset($GLOBALS['abort']) || $GLOBALS['abort'] !== true) {
+				core_devices_del($extdisplay,true);
+				core_devices_add($deviceid,$tech,$devinfo_dial,$devicetype,$deviceuser,$description,$emergency_cid,true);
+				needreload();
+				redirect_standard_continue('extdisplay');
+			}
+			break;
+			case "resetall":  //form a url with this option to nuke the AMPUSER & DEVICE trees and start over.
+				core_users2astdb();
+				core_devices2astdb();
+			break;
+	}
+	return true;
+}
+
+?>

Added: freepbx-modules/trunk/modules/core/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/install.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/install.php (added)
+++ freepbx-modules/trunk/modules/core/install.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,45 @@
+<?php
+
+$fcc = new featurecode('core', 'userlogon');
+$fcc->setDescription('User Logon');
+$fcc->setDefault('*11');
+$fcc->update();
+unset($fcc);
+
+$fcc = new featurecode('core', 'userlogoff');
+$fcc->setDescription('User Logoff');
+$fcc->setDefault('*12');
+$fcc->update();
+unset($fcc);
+
+$fcc = new featurecode('core', 'zapbarge');
+$fcc->setDescription('ZapBarge');
+$fcc->setDefault('888');
+$fcc->update();
+unset($fcc);
+
+$fcc = new featurecode('core', 'chanspy');
+$fcc->setDescription('ChanSpy');
+$fcc->setDefault('555');
+$fcc->update();
+unset($fcc);
+
+$fcc = new featurecode('core', 'simu_pstn');
+$fcc->setDescription('Simulate Incoming Call');
+$fcc->setDefault('7777');
+$fcc->update();
+unset($fcc);
+
+$fcc = new featurecode('core', 'simu_fax');
+$fcc->setDescription('Dial System FAX');
+$fcc->setDefault('666');
+$fcc->update();
+unset($fcc);
+
+$fcc = new featurecode('core', 'pickup');
+$fcc->setDescription('Call Pickup (Can be used with GXP-2000)');
+$fcc->setDefault('**');
+$fcc->update();
+unset($fcc);
+
+?>

Added: freepbx-modules/trunk/modules/core/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/module.xml?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/module.xml (added)
+++ freepbx-modules/trunk/modules/core/module.xml Mon Apr  7 13:18:05 2008
@@ -1,0 +1,67 @@
+<module>
+	<rawname>core</rawname>
+	<type>setup</type>
+	<category>Basic</category>
+	<name>Core</name>
+	<version>2.3.1.4</version>
+	<candisable>no</candisable>
+	<canuninstall>no</canuninstall>
+	<changelog>
+		*2.3.1.4* #2607 fix display problems with custom trunks starting with A, M or P
+		*2.3.1.3* added info to update checking tooltip providing info of what is transmitted
+		*2.3.1.2* #2526 dialout-trunk-predial-hook not always called, block queue login using queue number and fix to use AMPUSER
+		*2.3.1.1* #2459, #2565, #2467, #2357, #2359, #2411, #2402, #1697, #2470, #1974, #2493 - Fixed major that allowed blank/invalid users/devices/extensions
+		*2.3.1.0* #2372, #2384, #2408, remove double menu items (modules admin, dashboard), add macro-dialout-trunk-predial-hook
+		*2.3.0.3* #2308 FROM_DID to use ${EXTEN}, #2381 add iax_general_custom.conf, #2375 localization fixes
+		*2.3.0.2* #2330 allow '_' in route name changes, fix missing global variable.
+		*2.3.0.1* fix support link
+		*2.3.0.0* Final Release
+		*2.3.0RC1.3* #2295 generate bad-nubmer in core, disable with AMPBADNUMBER=false, #2172 replace | with ,
+		             #2299 except dialparties.agi, #2193 hard code paths, #2296 privacy manger for 1.4
+		*2.3.0RC1.2* #2253 remove default jbenable, jbforce, remove DeadAGI, #2189 add no-msg dest for vm
+		*2.3.0RC1.1* bump to RC1 because of bug not using proper version compare
+		*2.3.0rc1.0* bump for rc1
+		*2.3.0beta2.3.5* make wiki help link always accesible in database mode, fix for #2209, added includes to sip.conf, cleanup in dialparties.agi
+		*2.3.0beta2.3.4* #1748 utf-8 fix, #1759 password field not in database mode, #2215 Outbound Routes highlighting in lnav
+		*2.3.0beta2.3.3* fixed some uninitialized variables, #2210 trunk dialpatterns not being retrieved in gui
+		*2.3.0beta2.3.2* #2151 fix trunk ordering when more than 9 trunks used, and some unitialized vars
+		*2.3.0beta2.3.1* #2199 fix ENABLECW behavior on new extensions
+		*2.3.0beta2.3* added xml attribute needsenginedb, #2185 make MoH settings inheritable and add inherittable  MOHCLASS to dids/directdids with MoH
+		*2.3.0beta2.2* #1907 don't send ringing, #2055 language in *99 recording, #2168 dialparties to set sip header from SIPADDHEADER channel var
+		*2.3.0beta2.1* #2155 correct trunk tooltip, #2046 workaround for Asterisk bug that breaks VmX on some systems
+		*2.3.0beta2.0* Rearranged core destinations in drawselect box, added unavail and busy for vm, #1841 directdid with + fixed, #1329 recording with CID 
+ 		               number aliasing broken, fixed 1.4 ALERT_INFO deprecated use, added online update select box to general screen, and email where to send
+		               #2115 dial-by-name directory not saying supplied name
+		*2.3.0beta1.9* Added Call Waiting enable/disable on extensions settings, default for new is still set by ENABLECW
+		*2.3.0beta1.8.1* Added javascript validation to CID Prefix
+		*2.3.0beta1.8* Added CID Prefix Prepend feature to inbound DIDs
+		*2.3.0beta1.7* #2052 fix fixlocalprefix, bug introduced in 2.3.0beta1.6
+		*2.3.0beta1.6* #2042, #2046, auto generate asterisk path variables, remove amportal.conf parsing in dialparties.agi, remove other hardcoded paths
+		*2.3.0beta1.5* #2041, fix typo introduced in 2.3.0beta1.4 resultingin fixlocalprefix breaking
+		*2.3.0beta1.4* #1522 DeadAGI back to AGI, fixed Trunk Dial Rules tooltip, added wanrnings comments to agi-bin scripts
+		*2.3.0beta1.3* #1633 proper display after deleting, #1747 add South Africa to indications.conf, #2024 can't edit exten with directdid set
+		*2.3.0beta1.2* Changed CW default to on, changed freePBX to FreePBX
+		*2.3.0beta1.1* Change core destinations to from-did-direct from ext-local so that findmefollow is used if present
+		*2.3.0beta1.0* First release online upradeable core module
+		*1.2* Core modules code when part of framework
+	</changelog>
+	<depends>
+		<version>2.3.0beta2</version>
+	</depends>
+	<requirements>
+		<file>/usr/sbin/asterisk</file>
+	</requirements>
+	<menuitems>
+		<extensions needsenginedb="yes">Extensions</extensions>
+		<users needsenginedb="yes">Users</users>
+		<devices needsenginedb="yes">Devices</devices>
+		<did category="Inbound Call Control" sort="-5">Inbound Routes</did>
+		<routing>Outbound Routes</routing>
+		<trunks>Trunks</trunks>
+		<general>General Settings</general>
+		<ampusers>Administrators</ampusers>
+		<wiki type="tool" category="Support" sort="5" href="http://freepbx.org" target="_blank" access="all">FreePBX Support</wiki>
+	</menuitems>
+	<location>release/2.3/core-2.3.1.3.tgz</location>
+	<md5sum>03c8da3700d767dcb917229c589a1981</md5sum>
+</module>

Added: freepbx-modules/trunk/modules/core/page.ampusers.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/page.ampusers.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/page.ampusers.php (added)
+++ freepbx-modules/trunk/modules/core/page.ampusers.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,269 @@
+<?php /* $Id: page.ampusers.php 5071 2007-09-20 04:05:05Z gregmac $ */
+// routing.php Copyright (C) 2004 Greg MacLellan (greg at mtechsolutions.ca)
+// Asterisk Management Portal Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+
+$userdisplay = isset($_REQUEST['userdisplay'])?$_REQUEST['userdisplay']:'';
+$action = isset($_REQUEST['action'])?$_REQUEST['action']:'';
+$tech = isset($_REQUEST['tech'])?$_REQUEST['tech']:'';
+
+// populate some global variables from the request string
+$set_globals = array("username","password","extension_high","extension_low","deptname");
+foreach ($set_globals as $var) {
+	if (isset($_REQUEST[$var])) {
+		$$var = stripslashes( $_REQUEST[$var] );
+	}
+}
+
+//Search ALL active modules while generating admin access list
+$active_modules = module_getinfo(false, MODULE_STATUS_ENABLED);
+
+if(is_array($active_modules)){
+	foreach($active_modules as $key => $module) {
+		//create an array of module sections to display
+		if (isset($module['items']) && is_array($module['items'])) {
+			foreach($module['items'] as $itemKey => $item) {
+				$listKey = (!empty($item['display']) ? $item['display'] : $itemKey);
+				$module_list[ $listKey ] = $item;
+			}
+		}
+	}
+}
+
+// extensions vs device/users ... module_list setting
+if (isset($amp_conf["AMPEXTENSIONS"]) && ($amp_conf["AMPEXTENSIONS"] == "deviceanduser")) {
+       unset($module_list["extensions"]);
+} else {
+       unset($module_list["devices"]);
+       unset($module_list["users"]);
+}
+
+// no more adding the APPLY Changes bar to module list because array_multisort messes up integer array keys
+// $module_list['99'] = array('category' => NULL, 'name' => _("Apply Changes Bar"));
+
+// changed from $module_name to $admin_module_name because the former is used by framework
+foreach ($module_list as $key => $row) {
+	$module_category[$key] = $row['category'];
+	$admin_module_name[$key] = $row['name'];
+}
+array_multisort($module_category, SORT_ASC, $admin_module_name, SORT_ASC, $module_list);
+
+$sections = array();
+if (isset($_REQUEST["sections"])) {
+	if (is_array($_REQUEST["sections"])) {
+		$sections = $_REQUEST["sections"];
+	} else {
+		//TODO do we even need this??
+		$sections = explode(";",$_REQUEST["sections"]);
+	}
+}
+
+//if submitting form, update database
+switch ($action) {
+	case "addampuser":
+		core_ampusers_add($username, $password, $extension_low, $extension_high, $deptname, $sections);
+		//indicate 'need reload' link in footer.php 
+		needreload();
+		redirect_standard();
+	break;
+	case "editampuser":
+		core_ampusers_del($userdisplay);
+		core_ampusers_add($username, $password, $extension_low, $extension_high, $deptname, $sections);
+		//indicate 'need reload' link in footer.php 
+		needreload();
+		redirect_standard('userdisplay');
+	break;
+	case "delampuser":
+		core_ampusers_del($userdisplay);
+		//indicate 'need reload' link in footer.php 
+		needreload();
+		$userdisplay = ""; // go "add" screen
+		redirect_standard();
+	break;
+}
+
+?>
+</div>
+
+<div class="rnav">
+<ul>
+	<li><a <?php  echo ($userdisplay=='' ? 'class="current"':'') ?> href="config.php?display=<?php echo urlencode($display)?>"><?php echo _("Add User")?></a></li>
+<?php 
+//get existing trunk info
+$tresults = core_ampusers_list();
+
+foreach ($tresults as $tresult) {
+    echo "\t<li><a ".($userdisplay==$tresult[0] ? 'class="current"':'')." href=\"config.php?display=".urlencode($display)."&amp;userdisplay=".urlencode($tresult[0])."\">".$tresult[0]."</a></li>\n";
+}
+?>
+</ul>
+</div>
+
+<div class="content">
+
+<?php 
+
+	if ($userdisplay) {
+		echo "<h2>"._("Edit Administrator")."</h2>";
+		
+		$user = getAmpUser($userdisplay);
+		
+		$username = $user["username"];
+		$password = $user["password"];
+		$extension_high = $user["extension_high"];
+		$extension_low = $user["extension_low"];
+		$deptname = $user["deptname"];
+		$sections = $user["sections"];
+		
+?>
+		<p><a href="config.php?display=<?php echo urlencode($display) ?>&amp;userdisplay=<?php echo urlencode($userdisplay) ?>&amp;action=delampuser"><?php echo _("Delete User")?> <?php  echo $userdisplay; ?></a></p>
+<?php 
+
+	} else {
+		// set defaults
+		$username = "";
+		$password = "";
+		$deptname = "";
+		
+		$extension_low = "";
+		$extension_high = "";
+		
+		$sections = array("*");
+		
+	
+		echo "<h2>"._("Add Administrator")."</h2>";
+	} 
+?>
+	
+		<form autocomplete="off" name="ampuserEdit" action="config.php" method="get">
+			<input type="hidden" name="display" value="<?php echo $display?>"/>
+			<input type="hidden" name="userdisplay" value="<?php echo $userdisplay ?>"/>
+			<input type="hidden" name="action" value=""/>
+			<input type="hidden" name="tech" value="<?php echo $tech?>"/>
+			<table>
+			<tr>
+				<td colspan="2">
+					<h4><?php echo _("General Settings")?></h4>
+				</td>
+			</tr>
+<?php if ($amp_conf["AUTHTYPE"] != "database") { ?>			
+			<tr>
+				<td colspan="2">
+	<?php echo '<b>'._("NOTE:").'</b>'._("AUTHTYPE is not set to 'database' in /etc/amportal.conf - note that this module is not currently providing access control, and changing passwords here or adding users will have no effect unless AUTHTYPE is set to 'database'.") ?><br /><br />
+				</td>
+			</tr>
+<?php } ?>
+			<tr>
+				<td>
+					<a href=# class="info"><?php echo _("Username<span>Create a unique username for this new user</span>")?></a>: 
+				</td><td>
+					<input type="text" size="20" name="username" value="<?php echo $username;?>"/>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<a href=# class="info"><?php echo _("Password<span>Create a password for this new user</span>")?></a>: 
+				</td><td>
+					<input type="password" size="20" name="password" value="<?php echo $password;?>"/>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<br>
+					<h4><?php echo _("Access Restrictions")?></h4>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<a href=# class="info"><?php echo _("Department Name<span>Restrict this user's view of Digital Receptionist menus and System Recordings to only those for this department.</span>")?></a>: 
+				</td><td>
+					<input type="text" size="20" name="deptname" value="<?php echo htmlspecialchars($deptname);?>"/>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<a href=# class="info"><?php echo _("Extension Range<span>Restrict this user's view to only Extensions, Ring Groups, and Queues within this range.</span>")?></a>: 
+				</td><td>
+					<input type="text" size="5" name="extension_low" value="<?php echo htmlspecialchars($extension_low);?>"/>
+					&nbsp;to
+					<input type="text" size="5" name="extension_high" value="<?php echo htmlspecialchars($extension_high);?>"/>
+				</td>
+			</tr>
+			<tr>
+				<td valign="top">
+					<a href=# class="info"><?php echo _("Admin Access<span>Select the Admin Sections this user should have access to.</span>")?></a>: 
+				</td><td>&nbsp;
+					<select multiple name="sections[]">
+					<option />
+<?php 
+				$prev_category = NULL;
+				foreach ($module_list as $key => $row) {
+					if ($row['category'] != $prev_category) {
+						if ($prev_category)
+							echo "</optgroup>\n";
+						echo "<optgroup label=\""._($row['category'])."\">\n";
+						$prev_category = $row['category'];
+					}
+
+					echo "<option value=\"".$key."\"";
+					if (in_array($key, $sections)) echo " SELECTED";
+					echo ">"._($row['name'])."</option>\n";
+				}
+				echo "</optgroup>\n";
+
+				// Apply Changes Bar
+				echo "<option value=\"99\"";
+				if (in_array("99", $sections)) echo " SELECTED";
+				echo ">"._("Apply Changes Bar")."</option>\n";
+
+				// All Sections
+				echo "<option value=\"*\"";
+				if (in_array("*", $sections)) echo " SELECTED";
+				echo ">"._("ALL SECTIONS")."</option>\n";
+?>					
+					</select>
+				</td>
+			</tr>
+			
+			<tr>
+				<td colspan="2">
+					<h6><input name="Submit" type="button" value="<?php echo _("Submit Changes")?>" onclick="checkAmpUser(ampuserEdit, '<?php echo ($userdisplay ? "editampuser" : "addampuser") ?>')"></h6>
+				</td>
+			</tr>
+			</table>
+		</form>
+
+<script language="javascript">
+<!--
+
+function checkAmpUser(theForm, action) {
+	$username = theForm.username.value;
+	$deptname = theForm.deptname.value;
+	
+	if ($username == "") {
+		<?php echo "alert('"._("Username must not be blank")."')"?>;
+	} else if (!$username.match('^[a-zA-Z][a-zA-Z0-9]+$')) {
+		<?php echo "alert('"._("Username cannot start with a number, and can only contain letters and numbers")."')"?>;
+	} else if ($deptname == "default") {
+		<?php echo "alert('"._("For security reasons, you cannot use the department name default")."')"?>;
+	} else if ($deptname != "" && !$deptname.match('^[a-zA-Z0-9]+$')) {
+		<?php echo "alert('"._("Department name cannot have a space")."')"?>;
+	} else {
+		theForm.action.value = action;
+		theForm.submit();
+	}
+}
+
+//-->
+</script>
+

Added: freepbx-modules/trunk/modules/core/page.devices.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/page.devices.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/page.devices.php (added)
+++ freepbx-modules/trunk/modules/core/page.devices.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,20 @@
+<?php /* $Id: page.devices.php 2617 2006-09-26 11:43:51Z qldrob $ */
+//Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+?>
+<div class="rnav">
+<?php 
+$devices = core_devices_list();
+drawListMenu($devices, $skip, $type, $display, $extdisplay, _("Device"));
+?>
+</div>

Added: freepbx-modules/trunk/modules/core/page.did.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/page.did.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/page.did.php (added)
+++ freepbx-modules/trunk/modules/core/page.did.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,332 @@
+<?php /* $Id: page.did.php 4905 2007-08-21 04:41:29Z p_lindheimer $ */
+//Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+	
+$action = isset($_REQUEST['action'])?$_REQUEST['action']:'';
+$extdisplay= isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:'';
+$dispnum = 'did'; //used for switch on config.php
+$account = isset($_REQUEST['account'])?$_REQUEST['account']:'';
+$goto = isset($_REQUEST['goto0'])?$_REQUEST['goto0']:'';
+$ringing = isset($_REQUEST['ringing'])?$_REQUEST['ringing']:'';
+$description = isset($_REQUEST['description'])?$_REQUEST['description']:'';
+
+//update db if submiting form
+switch ($action) {
+	case 'addIncoming':
+		//create variables from request
+		extract($_REQUEST);
+		//add details to teh 'incoming' table
+		if (core_did_add($_REQUEST)) {
+			needreload();
+			redirect_standard();
+		}
+	break;
+	case 'delIncoming':
+		$extarray=explode('/',$extdisplay,3);
+		core_did_del($extarray[0],$extarray[1],$extarray[2]);
+		needreload();
+		redirect_standard();
+	break;
+	case 'edtIncoming':
+		$extarray=explode('/',$extdisplay,3);
+		if (core_did_edit($extarray[0],$extarray[1],$extarray[2],$_REQUEST)) {
+			needreload();
+			redirect_standard('extdisplay');
+		}
+	break;
+}
+
+?>
+</div>
+
+<div class="rnav">
+<ul>
+	<li><a <?php echo ($extdisplay=='' ? 'class="current"':'') ?> href="config.php?display=<?php echo urlencode($dispnum)?>"><?php echo _("Add Incoming Route")?></a></li>
+<?php 
+//get unique incoming routes
+$inroutes = core_did_list('description');
+if (isset($inroutes)) {
+	foreach ($inroutes as $inroute) {
+		$displaydid = ( empty($inroute['extension'])? _("any DID") : $inroute['extension'] );
+ 		$displaycid = ( empty($inroute['cidnum'])? _("any CID") : $inroute['cidnum'] );
+		$zapchan = ( strlen($inroute['channel'])? "Zaptel Channel {$inroute['channel']}" : "" );
+		$desc = ( empty($inroute['description'])? "" : $inroute['description']."<br />" );
+		if ($zapchan != "") 
+			echo "\t<li><a ".($extdisplay==$inroute['extension']."/".$inroute['cidnum']."/".$inroute['channel'] ? 'class="current"':'')." href=\"config.php?display=".urlencode($dispnum)."&amp;extdisplay=".urlencode($inroute['extension'])."/".urlencode($inroute['cidnum'])."/".urlencode($inroute['channel'])."\">{$desc} {$zapchan} </a></li>\n";
+		else
+			echo "\t<li><a ".($extdisplay==$inroute['extension']."/".$inroute['cidnum']."/".$inroute['channel'] ? 'class="current"':'')." href=\"config.php?display=".urlencode($dispnum)."&amp;extdisplay=".urlencode($inroute['extension'])."/".urlencode($inroute['cidnum'])."/".urlencode($inroute['channel'])."\">{$desc} {$displaydid} / {$displaycid} </a></li>\n";
+	}
+}
+?>
+</ul>
+</div>
+
+<div class="content">
+<?php 
+	
+	if ($action == 'delIncoming') {
+		echo '<br><h3>Route '.$extdisplay.' '._("deleted").'!</h3><br><br><br><br><br><br><br><br>';
+	} else {
+		$delURL = $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'].'&action=delIncoming';
+?>
+<?php if ($extdisplay) {	
+	//create variables for the selected route's settings
+	$extarray=explode('/',$extdisplay,3);
+	$ininfo=core_did_get($extarray[0],$extarray[1],$extarray[2]);
+	if (is_array($ininfo)) extract($ininfo);
+?>
+		<h2><?php echo _("Route")?>: <?php echo !empty($description)?$description:$extdisplay; ?></h2>
+		<p><a href="<?php echo $delURL ?>"><?php echo _("Delete Route")?> <?php echo !empty($description)?$description:$extdisplay ?></a></p>
+<?php } else { ?>
+		<h2><?php echo _("Add Incoming Route")?></h2>
+<?php } ?>
+		<form name="editGRP" action="<?php $_SERVER['PHP_SELF'] ?>" method="post" onsubmit="return editGRP_onsubmit();">
+		<input type="hidden" name="display" value="<?php echo $dispnum?>">
+		<input type="hidden" name="action" value="<?php echo ($extdisplay ? 'edtIncoming' : 'addIncoming') ?>">
+		<input type="hidden" name="extdisplay" value="<?php echo $extdisplay ?>">
+		<table>
+		<tr><td colspan="2"><h5><?php echo ($extdisplay ? _('Edit Incoming Route') : _('Add Incoming Route')) ?><hr></h5></td></tr>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("Description")?><span><?php echo _('Provide a meaningful description of what this incoming route is')?></span></a>:</td>
+			<td><input type="text" name="description" value="<?php echo htmlspecialchars(isset($description)?$description:''); ?>"></td>
+		</tr>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("DID Number")?><span><?php echo _('Define the expected DID Number if your trunk passes DID on incoming calls. <br><br>Leave this blank to match calls with any or no DID info.<br><br>You can also use a pattern match (eg _2[345]X) to match a range of numbers')?></span></a>:</td>
+			<td><input type="text" name="extension" value="<?php echo htmlspecialchars(isset($extension)?$extension:''); ?>"></td>
+		</tr>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("Caller ID Number")?><span><?php echo _('Define the Caller ID Number to be matched on incoming calls.<br><br>Leave this field blank to match any or no CID info.')?></span></a>:</td>
+			<td><input type="text" name="cidnum" value="<?php echo htmlspecialchars(isset($cidnum)?$cidnum:'') ?>"></td>
+		</tr>
+		<tr><td><h4><?php echo _("OR"); ?></h4></td></tr>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("Zaptel Channel")?><span><?php echo _('Match calls that come in on this specific Zaptel channel number. zapata.conf must have "context=from-zaptel" rather than context="from-pstn" to use this feature')?></span></a>:</td>
+			<td><input type="text" name="channel" value="<?php echo htmlspecialchars(isset($channel)?$channel:''); ?>"></td>
+		</tr>
+		<tr>
+			<td><br></td>
+		</tr>
+		<tr><td colspan="2"><h5><?php echo _("Fax Handling")?><hr></h5></td></tr>
+		<tr>
+			<td>
+				<a class="info" href="#"><?php echo _("Fax Extension")?><span><?php echo _("Select 'system' to have the system receive and email faxes.<br><br>The FreePBX default is defined in General Settings.")?></span></a>:
+			</td>
+			<td>&nbsp;
+				<select name="faxexten">
+<?php 
+// Cleaning up warnings. I should do this a better way.
+if (!isset($faxexten))
+	$faxexten = null;
+if (!isset($faxemail))
+	$faxemail = null;
+if (!isset($answer))
+	$answer = '0';
+if (!isset($alertinfo))
+	$alertinfo = 0;
+if (!isset($mohclass))
+	$mohclass = 'default';
+if (!isset($grppre))
+	$grppre = "";
+?>
+					<option value="default" <?php  echo ($faxexten == 'default' ? 'SELECTED' : '')?>><?php echo _("FreePBX default")?>
+					<option value="disabled" <?php  echo ($faxexten == 'disabled' ? 'SELECTED' : '')?>><?php echo _("disabled")?>
+					<option value="system" <?php  echo ($faxexten == 'system' ? 'SELECTED' : '')?>><?php echo _("system")?>
+			<?php 
+				//get unique devices
+				$devices = core_devices_list();
+				if (isset($devices)) {
+					foreach ($devices as $device) {
+						echo '<option value="'.$device[0].'" '.($faxexten == $device[0] ? 'SELECTED' : '').'>'.$device[1].' &lt;'.$device[0].'&gt;';
+					}
+				}
+			?>	
+				</select>
+			</td>
+		</tr>
+		<tr>
+			<td>
+				<a class="info" href="#"><?php echo _("Fax Email")?><span><?php echo _("Email address is used if 'system' has been chosen for the fax extension above.<br><br>Leave this blank to use the FreePBX default in General Settings.")?></span></a>:
+			</td>
+			<td>
+				<input type="text" size="20" name="faxemail" value="<?php echo htmlspecialchars($faxemail)?>"/>
+			</td>
+		</tr>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("Fax Detection Type")?><span><?php echo _('Selecting Zaptel or NVFax will immediately answer the call and play ringing tones to the caller for the number of seconds in Pause below. Use NVFax on SIP or IAX trunks.')?></span></a>:</td>
+			<td>&nbsp;
+				<select name="answer">
+					<option value="0" <?php  echo ($answer == '0' ? 'SELECTED' : '')?>><?php echo _("None")?>
+					<option value="1" <?php  echo ($answer == '1' ? 'SELECTED' : '')?>><?php echo _("Zaptel")?>
+					<option value="2" <?php  echo ($answer == '2' ? 'SELECTED' : '')?>><?php echo _("NVFax")?>
+				</select>
+			</td>
+		</tr>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("Pause after answer")?><span><?php echo _('The number of seconds we should wait after performing an Immediate Answer. The primary purpose of this is to pause and listen for a fax tone before allowing the call to proceed.')?></span></a>:</td>
+			<td><input type="text" name="wait" size="3" value="<?php echo isset($wait)?$wait:'' ?>"></td>
+		</tr>
+		<tr>
+			<td><br></td>
+		</tr>
+<?php
+if (!isset($privacyman))
+	$privacyman = '0';
+?>
+		<tr><td colspan="2"><h5><?php echo _("Privacy")?><hr></h5></td></tr>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("Privacy Manager")?><span><?php echo _('If no Caller ID is sent, Privacy Manager will asks the caller to enter their 10 digit phone number. The caller is given 3 attempts.')?></span></a>:</td>
+			<td>
+				<select name="privacyman">
+					<option value="0" <?php  echo ($privacyman == '0' ? 'SELECTED' : '')?>><?php echo _("No")?>
+					<option value="1" <?php  echo ($privacyman == '1' ? 'SELECTED' : '')?>><?php echo _("Yes")?>
+				</select>
+			</td>
+		</tr>
+		<tr>
+			<td><br></td>
+		</tr>		
+		
+		<tr><td colspan="2"><h5><?php echo _("Options")?><hr></h5></td></tr>
+
+
+
+		<tr>
+			<td><a href="#" class="info"><?php echo _("Alert Info")?><span><?php echo _('ALERT_INFO can be used for distinctive ring with SIP devices.')?></span></a>:</td>
+			<td><input type="text" name="alertinfo" size="10" value="<?php echo ($alertinfo)?$alertinfo:'' ?>"></td>
+		</tr>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("CID name prefix")?>:<span><?php echo _('You can optionally prefix the Caller ID name. ie: If you prefix with "Sales:", a call from John Doe would display as "Sales:John Doe" on the extensions that ring.')?></span></a>:</td>
+			<td><input type="text" name="grppre" size="10" value="<?php echo ($grppre)?$grppre:'' ?>"></td>
+		</tr>
+<?php   if (function_exists('music_list')) { ?>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("Music On Hold?")?><span><?php echo _("Set the MoH class that will be used for calls that come in on this route. For example, choose a type appropriate for routes coming in from a country which may have announcements in their language.")?></span></a></td>
+			<td>
+				&nbsp;&nbsp;<select name="mohclass"/>
+				<?php
+					$tresults = music_list($amp_conf['ASTVARLIBDIR']."/mohmp3");
+					$cur = (isset($mohclass) && $mohclass != "" ? $mohclass : 'default');
+					echo '<option value="none">'._("No Music")."</option>";
+					if (isset($tresults[0])) {
+						foreach ($tresults as $tresult) {
+							echo '<option value="'.$tresult.'"'.($tresult == $cur ? ' SELECTED' : '').'>'.$tresult."</option>\n";
+						}
+					}
+				?>		
+				</select>		
+			</td>
+		</tr>
+<?php } ?>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("Signal RINGING")?><span><?php echo _('Some devices or providers require RINGING to be sent before ANSWER. You\'ll notice this happening if you can send calls directly to a phone, but if you send it to an IVR, it won\'t connect the call.')?></span></a>:</td>
+			<td><input type="checkbox" name="ringing" value="CHECKED" <?php echo $ringing ?> /></td>
+		</tr>
+
+
+<?php
+	// implementation of module hook
+	// object was initialized in config.php
+	echo $module_hook->hookHtml;
+?>
+
+		<tr>
+			<td><br></td>
+		</tr>		
+		
+		<tr><td colspan="2"><h5><?php echo _("Set Destination")?><hr></h5></td></tr>
+		
+<?php 
+//draw goto selects
+echo drawselects(isset($destination)?$destination:null,0);
+?>
+		
+		<tr>
+		<td colspan="2"><br><h6>
+			<input name="Submit" type="submit" value="<?php echo _("Submit")?>">
+		</h6></td>		
+		
+		</tr>
+		</table>
+<script language="javascript">
+<!--
+
+var theForm = document.editGRP;
+
+theForm.extension.focus();
+
+function editGRP_onsubmit() {
+	var msgInvalidDIDNumb = "<?php echo _('Please enter a valid DID Number'); ?>";
+	var msgInvalidCIDNum = "<?php echo _('Please enter a valid Caller ID Number'); ?>";
+	var msgCidDidWithZaptel = "<?php echo _('DID number and CID number MUST be blank when used with zaptel channel routing'); ?>";
+	var msgInvalidFaxEmail = "<?php echo _('Please enter a valid Fax Email or leave it empty to use the default'); ?>";
+	var msgInvalidPause = "<?php echo _('Please enter a valid number for Pause after answer'); ?>";
+	var msgConfirmDIDCIDBlank = "<?php echo _('Leaving the DID Number AND the Caller ID Number empty will match all incoming calls received not routed using any other defined Incoming Route.\n\nAre you sure?'); ?>";
+	var msgConfirmDIDNonStd = "<?php echo _('DID information is normally just an incoming telephone number or for advanced users, a valid Asterisk Dial Pattern\n\nYou have entered a non standard DID pattern.\n\nAre you sure this is correct?'); ?>";
+	var msgConfirmDIDNoSlash = "<?php echo _('A Slash (\'/\') is never a valid DID. Please remove it and try again'); ?>";
+	var msgInvalidGrpPrefix = "<?php echo _('Invalid Caller ID prefix.'); ?>";
+	
+	setDestinations(theForm,1);
+	
+	defaultEmptyOK = true;
+	if (!isDialpattern(theForm.extension.value)) {
+		// warn the user that DID is normally numbers
+		if (!confirm(msgConfirmDIDNonStd))
+			return false;
+	}
+	
+	if (isInside(theForm.extension.value, "/")) {
+		warnInvalid(theForm.extension, msgConfirmDIDNoSlash);
+		return false;
+	}
+	if (!isDialpattern(theForm.cidnum.value))
+		return warnInvalid(theForm.cidnum, msgInvalidCIDNum);
+	
+	if (!isEmail(theForm.faxemail.value))
+		return warnInvalid(theForm.faxemail, msgInvalidFaxEmail);
+	
+	if (!isInteger(theForm.wait.value))
+		return warnInvalid(theForm.wait, msgInvalidPause);
+	
+	if (!validateDestinations(theForm,1,true))
+		return false;
+	
+	if (theForm.extension.value != ""  && theForm.channel.value != "" ) {
+		return warnInvalid(theForm.extension, msgCidDidWithZaptel);
+	}
+	if (theForm.cidnum.value != ""  && theForm.channel.value != "" ) {
+		return warnInvalid(theForm.cidnum, msgCidDidWithZaptel);
+	}
+	// warning about 'any DID / any CID'
+	if (theForm.extension.value == "" && theForm.cidnum.value == "" && theForm.channel.value == "" ) {
+		if (!confirm(msgConfirmDIDCIDBlank))
+			return false;
+	}
+	defaultEmptyOK = true;
+	if (!isCallerID(theForm.grppre.value))
+		return warnInvalid(theForm.grppre, msgInvalidGrpPrefix);
+	
+	return true;
+}
+
+//-->
+</script>
+		</form>
+<?php 		
+	} //end if action == delGRP
+	
+
+?>
+
+
+
+
+

Added: freepbx-modules/trunk/modules/core/page.extensions.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/page.extensions.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/page.extensions.php (added)
+++ freepbx-modules/trunk/modules/core/page.extensions.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,21 @@
+<?php /* $Id: page.extensions.php 2842 2006-10-26 16:03:30Z diego_iastrubni $ */
+//Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+?>
+
+<div class="rnav">
+<?php 
+$extens = core_users_list();
+drawListMenu($extens, $skip, $type, $display, $extdisplay, _("Extension"));
+?>
+	<br />
+</div>

Added: freepbx-modules/trunk/modules/core/page.general.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/page.general.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/page.general.php (added)
+++ freepbx-modules/trunk/modules/core/page.general.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,418 @@
+<?php /* $Id: page.general.php 5519 2007-12-16 20:20:48Z p_lindheimer $ */
+//Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+$action = isset($_REQUEST['action'])?$_REQUEST['action']:'';
+
+$cm =& cronmanager::create($db);
+
+
+//if submitting form, update database
+if ($action == 'editglobals') {
+	$globalfields = array(
+						array($_REQUEST['RINGTIMER'],'RINGTIMER'),
+						array($_REQUEST['FAX_RX'],'FAX_RX'),
+						array($_REQUEST['FAX_RX_EMAIL'],'FAX_RX_EMAIL'),
+						array($_REQUEST['FAX_RX_FROM'],'FAX_RX_FROM'),
+						array($_REQUEST['DIRECTORY'],'DIRECTORY'),
+						array($_REQUEST['VM_PREFIX'],'VM_PREFIX'),
+						array($_REQUEST['VM_DDTYPE'],'VM_DDTYPE'),
+						array($_REQUEST['VM_GAIN'],'VM_GAIN'),
+						array($_REQUEST['DIAL_OPTIONS'],'DIAL_OPTIONS'),
+						array($_REQUEST['TRUNK_OPTIONS'],'TRUNK_OPTIONS'),
+						array($_REQUEST['TONEZONE'], 'TONEZONE'),
+						array($_REQUEST['TIMEFORMAT'], 'TIMEFORMAT'),
+						array($_REQUEST['ALLOW_SIP_ANON'], 'ALLOW_SIP_ANON'),
+						array($_REQUEST['OPERATOR_XTN'], 'OPERATOR_XTN'),
+						array(isset($_REQUEST['DIRECTORY_OPTS']) ? $_REQUEST['DIRECTORY_OPTS'] : "",'DIRECTORY_OPTS'),
+						array(isset($_REQUEST['VM_OPTS']) ? $_REQUEST['VM_OPTS'] : "",'VM_OPTS'),
+
+						array(isset($_REQUEST['VMX_CONTEXT']) ? $_REQUEST['VMX_CONTEXT'] : "",'VMX_CONTEXT'),
+						array(isset($_REQUEST['VMX_PRI']) ? $_REQUEST['VMX_PRI'] : "",'VMX_PRI'),
+						array(isset($_REQUEST['VMX_TIMEDEST_CONTEXT']) ? $_REQUEST['VMX_TIMEDEST_CONTEXT'] : "",'VMX_TIMEDEST_CONTEXT'),
+						array(isset($_REQUEST['VMX_TIMEDEST_EXT']) ? $_REQUEST['VMX_TIMEDEST_EXT'] : "",'VMX_TIMEDEST_EXT'),
+						array(isset($_REQUEST['VMX_TIMEDEST_PRI']) ? $_REQUEST['VMX_TIMEDEST_PRI'] : "",'VMX_TIMEDEST_PRI'),
+						array(isset($_REQUEST['VMX_LOOPDEST_CONTEXT']) ? $_REQUEST['VMX_LOOPDEST_CONTEXT'] : "",'VMX_LOOPDEST_CONTEXT'),
+						array(isset($_REQUEST['VMX_LOOPDEST_EXT']) ? $_REQUEST['VMX_LOOPDEST_EXT'] : "",'VMX_LOOPDEST_EXT'),
+						array(isset($_REQUEST['VMX_LOOPDEST_PRI']) ? $_REQUEST['VMX_LOOPDEST_PRI'] : "",'VMX_LOOPDEST_PRI'),
+						array(isset($_REQUEST['VMX_OPTS_TIMEOUT']) ? $_REQUEST['VMX_OPTS_TIMEOUT'] : "",'VMX_OPTS_TIMEOUT'),
+						array(isset($_REQUEST['VMX_OPTS_LOOP']) ? $_REQUEST['VMX_OPTS_LOOP'] : "",'VMX_OPTS_LOOP'),
+						array(isset($_REQUEST['VMX_OPTS_DOVM']) ? $_REQUEST['VMX_OPTS_DOVM'] : "",'VMX_OPTS_DOVM'),
+						array(isset($_REQUEST['VMX_TIMEOUT']) ? $_REQUEST['VMX_TIMEOUT'] : "",'VMX_TIMEOUT'),
+						array(isset($_REQUEST['VMX_REPEAT']) ? $_REQUEST['VMX_REPEAT'] : "",'VMX_REPEAT'),
+						array(isset($_REQUEST['VMX_LOOPS']) ? $_REQUEST['VMX_LOOPS'] : "",'VMX_LOOPS'),
+						);
+
+	$compiled = $db->prepare('UPDATE globals SET value = ? WHERE variable = ?');
+	//$compiled = $db->prepare('REPLACE INTO globals (value,variable) VALUES (?, ?)');
+	$result = $db->executeMultiple($compiled,$globalfields);
+	if(DB::IsError($result)) {
+		echo $action.'<br>';
+		die_freepbx($result->getMessage());
+	}
+	
+	/* update online updates and email as appropriate
+	*/
+	$online_updates = isset($_REQUEST['online_updates'])? $_REQUEST['online_updates'] : 'yes';
+	$update_email   = isset($_REQUEST['update_email'])  ? $_REQUEST['update_email']   : '';
+
+	if ($online_updates == 'yes') {
+		$cm->enable_updates();
+	} else {
+		$cm->disable_updates();
+	}
+
+	// TODO: maybe check the email address a bit better server/client side
+	//
+	$cm->save_email($update_email);
+	
+	//indicate 'need reload' link in header.php 
+	needreload();
+}
+
+$online_updates = $cm->updates_enabled() ? 'yes' : 'no';
+$update_email   = $cm->get_email();
+
+//get all rows relating to selected account
+$sql = "SELECT * FROM globals";
+$globals = $db->getAll($sql);
+if(DB::IsError($globals)) {
+die_freepbx($globals->getMessage());
+}
+
+//create a set of variables that match the items in global[0]
+foreach ($globals as $global) {
+	${trim($global[0])} = $global[1];	
+}
+
+?>
+
+<form name="general" action="config.php" method="post" onsubmit="return general_onsubmit();">
+<input type="hidden" name="display" value="general"/>
+<input type="hidden" name="action" value="editglobals"/>
+
+<h5><?php echo _("Dialing Options")?></h5>
+<p>
+	<a href=# class="info"><?php echo _("Asterisk Dial command options:")?><span><br>
+<?php echo _("t: Allow the called user to transfer the call by hitting #")?><br>
+<?php echo _("T: Allow the calling user to transfer the call by hitting #")?><br>
+<?php echo _("r: Generate a ringing tone for the calling party")?><br>
+<?php echo _("w: Allow the called user to start recording after pressing *1 (Asterisk v1.2)")?><br>
+<?php echo _("W: Allow the calling user to start recording after pressing *1 (Asterisk v1.2)")?><br>
+	</span></a>
+	<input type="text" size="2" name="DIAL_OPTIONS" value="<?php  echo htmlspecialchars($DIAL_OPTIONS)?>"/>
+	<br><br>
+	<a href=# class="info"><?php echo _("Asterisk Outbound Dial command options:")?><span><br>
+<?php echo _("t: Allow the called user to transfer the call by hitting #")?><br>
+<?php echo _("T: Allow the calling user to transfer the call by hitting #")?><br>
+<?php echo _("w: Allow the called user to start recording after pressing *1 (Asterisk v1.2)")?><br>
+<?php echo _("W: Allow the calling user to start recording after pressing *1 (Asterisk v1.2)")?><br>
+<?php echo _("r: You SHOULD NOT use this option on outbound trunks")?><br>
+	</span></a>
+	<input type="text" size="2" name="TRUNK_OPTIONS" value="<?php  echo htmlspecialchars($TRUNK_OPTIONS)?>"/>
+</p>
+
+<h5><?php echo _("Voicemail")?></h5>
+<p>
+	<?php echo _("Number of seconds to ring phones before sending callers to voicemail:")?>
+	<input type="text" size="2" name="RINGTIMER" value="<?php  echo htmlspecialchars($RINGTIMER)?>"/>
+	<br><br>
+	<?php echo _("Extension prefix for dialing direct to voicemail:")?>
+	<input type="text" size="2" name="VM_PREFIX" value="<?php  echo htmlspecialchars($VM_PREFIX)?>"/>
+	<br><br>
+	<?php echo _("Direct Dial to Voicemail message type:")?>
+	<select name="VM_DDTYPE">
+	<option value=""><?php echo _("Default"); ?></option>
+	<option value="u"<?php if ($VM_DDTYPE == "u") echo " SELECTED"; ?>><?php echo _("Unavailable"); ?></option>
+	<option value="su"<?php if ($VM_DDTYPE == "su") echo " SELECTED"; ?>><?php echo _("Unavailable")."--"._("no instructions"); ?></option>
+	<option value="b"<?php if ($VM_DDTYPE == "b") echo " SELECTED"; ?>><?php echo _("Busy"); ?></option>
+	<option value="sb"<?php if ($VM_DDTYPE == "sb") echo " SELECTED"; ?>><?php echo _("Busy")."--"._("no instructions"); ?></option>
+	<option value="s"<?php if ($VM_DDTYPE == "s") echo " SELECTED"; ?>><?php echo ("No Message"); ?></option>
+	</select>
+	<br><br>
+	<a href=# class="info"><?php echo _("Use gain when recording the voicemail message (optional):")?><span>
+	<?php echo _("Use the specified amount of gain when recording the voicemail message."); ?><br><br>
+	<?php echo _("The units are whole-number decibels (dB)."); ?></span></a>
+	<input type="text" size="2" name="VM_GAIN" value="<?php  echo htmlspecialchars($VM_GAIN)?>"/>
+	<br><br>
+	<input type="checkbox" value="s" name="VM_OPTS" <?php  echo ($VM_OPTS ? 'CHECKED' : '')?>> <a href=# class="info"><?php echo _("Do Not Play")?><span><?php echo _("Check this to remove the default message \"Please leave your message after the tone. When done, hang-up, or press the pound key.\" That is played after the voicemail greeting (the s option). This applies globally to all vm boxes.")?></span></a> <?php echo _("please leave message after tone to caller")?>
+</p>
+
+<h5><?php echo _("Voicemail VmX Locator")?></h5>
+	<table>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Default Context & Pri:")?><span>
+			<?php echo _("Default to use if only an number/extension are provided."); ?></span></a>
+			</td>
+			<td><input type="text" size="18" name="VMX_CONTEXT" value="<?php  echo htmlspecialchars($VMX_CONTEXT)?>"/><small><?php echo _("context")?></small></td>
+			<td></td>
+			<td><input type="text" size="2" name="VMX_PRI" value="<?php  echo htmlspecialchars($VMX_PRI)?>"/><small><?php echo _("pri")?></small></td>
+		</tr>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Timeout/#-press default:")?><span>
+			<?php echo _("This is the default location that a caller will be sent if they don't press any key (timeout) or press # which is interpreted as a timeout. Set this to 'dovm' to go to voicemail (default)."); ?></span></a>
+			</td>
+			<td><input type="text" size="18" name="VMX_TIMEDEST_CONTEXT" value="<?php  echo htmlspecialchars($VMX_TIMEDEST_CONTEXT)?>"/><small><?php echo _("context")?></small></td>
+			<td><input type="text" size="4" name="VMX_TIMEDEST_EXT" value="<?php  echo htmlspecialchars($VMX_TIMEDEST_EXT)?>"/><small><?php echo _("exten")?></small></td>
+			<td><input type="text" size="2" name="VMX_TIMEDEST_PRI" value="<?php  echo htmlspecialchars($VMX_TIMEDEST_PRI)?>"/><small><?php echo _("pri")?></small></td>
+		</tr>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Loop Exceed default:")?><span>
+			<?php echo _("This is the default location that a caller will be sent if they press an invalid options too man times, as defined by the Maximum Loops count. Set this to 'dovm' to go to voicemail (default)."); ?></span></a>
+			</td>
+			<td><input type="text" size="18" name="VMX_LOOPDEST_CONTEXT" value="<?php  echo htmlspecialchars($VMX_LOOPDEST_CONTEXT)?>"/><small><?php echo _("context")?></small></td>
+			<td><input type="text" size="4" name="VMX_LOOPDEST_EXT" value="<?php  echo htmlspecialchars($VMX_LOOPDEST_EXT)?>"/><small><?php echo _("exten")?></small></td>
+			<td><input type="text" size="2" name="VMX_LOOPDEST_PRI" value="<?php  echo htmlspecialchars($VMX_LOOPDEST_PRI)?>"/><small><?php echo _("pri")?></small></td>
+		</tr>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Timeout VM Msg:")?><span>
+			<?php echo _("If this destination is voicemail, select whether or not to play the standard voicemail instructions or just beep."); ?></span></a>
+			</td>
+			<td align=right>
+			<select name="VMX_OPTS_TIMEOUT">
+				<option value=""  <?php  echo ($VMX_OPTS_TIMEOUT == '' ? 'SELECTED' : '') ?>><?php echo _("Std Instructions")?>
+				<option value="s" <?php  echo ($VMX_OPTS_TIMEOUT == 's' ? 'SELECTED' : '')?>><?php echo _("Beep Only")?>
+			</select> 
+			</td>
+		</tr>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Max Loop VM Msg:")?><span>
+			<?php echo _("If this destination is voicemail, select whether or not to play the standard voicemail instructions or just beep."); ?></span></a>
+			</td>
+			<td align=right>
+			<select name="VMX_OPTS_LOOP">
+				<option value=""  <?php  echo ($VMX_OPTS_LOOP == '' ? 'SELECTED' : '') ?>><?php echo _("Std Instructions")?>
+				<option value="s" <?php  echo ($VMX_OPTS_LOOP == 's' ? 'SELECTED' : '')?>><?php echo _("Beep Only")?>
+			</select> 
+			</td>
+		</tr>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Direct VM Option")?><span>
+			<?php echo _("If a user defined option is to go to voicmail (using the 'dovm' extension) this is the default option if not specified by the user's settings."); ?></span></a>
+			</td>
+			<td align=right>
+			<select name="VMX_OPTS_DOVM">
+				<option value=""  <?php  echo ($VMX_OPTS_DOVM == '' ? 'SELECTED' : '') ?>><?php echo _("Std Instructions")?>
+				<option value="s" <?php  echo ($VMX_OPTS_DOVM == 's' ? 'SELECTED' : '')?>><?php echo _("Beep Only")?>
+			</select> 
+			</td>
+		</tr>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Msg Timeout:")?><span>
+			<?php echo _("Time ot wait after message has played to timeout and/or repeat the message if no entry pressed."); ?></span></a>
+			</td>
+			<td align=right>
+			<select name="VMX_TIMEOUT">
+<?php
+			for ($i=0;$i<16;$i++) { 
+				$VMX_TIMEOUT = (!isset($VMX_TIMEOUT) || $VMX_TIMEOUT == '')?2:$VMX_TIMEOUT;
+?>
+				<option value="<?php echo $i?>"  <?php  echo ($VMX_TIMEOUT == $i ? 'SELECTED' : '') ?>><?php echo $i?>
+<?php
+				}
+?>
+			</select></td><td><small><?php echo _("seconds")?></small>
+			</td>
+		</tr>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Msg Play:")?><span>
+			<?php echo _("Number of times to play the recorded message if the caller does not press any options and it times out."); ?></span></a>
+			</td>
+			<td align=right>
+			<select name="VMX_REPEAT">
+<?php
+			for ($i=1;$i<5;$i++) { 
+				$VMX_REPEAT = (!isset($VMX_REPEAT) || $VMX_REPEAT == '')?1:$VMX_REPEAT;
+?>
+				<option value="<?php echo $i?>"  <?php  echo ($VMX_REPEAT == $i ? 'SELECTED' : '') ?>><?php echo $i?>
+<?php
+				}
+?>
+			</select></td><td><small><?php echo _("times")?></small> 
+			</td>
+		</tr>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Error Re-tries:")?><span>
+			<?php echo _("Number of times to play invalid options and repeat the message upon receiving an undefined option."); ?></span></a>
+			</td>
+			<td align=right>
+			<select name="VMX_LOOPS">
+<?php
+			for ($i=1;$i<5;$i++) { 
+				$VMX_REPEAT = (!isset($VMX_LOOPS) || $VMX_LOOPS == '')?1:$VMX_LOOPS;
+?>
+				<option value="<?php echo $i?>"  <?php  echo ($VMX_LOOPS == $i ? 'SELECTED' : '') ?>><?php echo $i?>
+<?php
+				}
+?>
+			</select></td><td><small><?php echo _("times")?></small> 
+			</td>
+		</tr>
+	</table>
+<p>
+
+</p>
+
+<h5><?php echo _("Company Directory")?></h5>
+<p>
+	<?php echo _("Find users in the Company Directory by:")?>
+	<select name="DIRECTORY">
+		<option value="first" <?php  echo ($DIRECTORY == 'first' ? 'SELECTED' : '')?>><?php echo _("first name")?>
+		<option value="last" <?php  echo ($DIRECTORY == 'last' ? 'SELECTED' : '')?>><?php echo _("last name")?>
+		<option value="both" <?php  echo ($DIRECTORY == 'both' ? 'SELECTED' : '')?>><?php echo _("first or last name")?>
+	</select> 
+	<br><br>
+	<input type="checkbox" value="e" name="DIRECTORY_OPTS" <?php  echo ($DIRECTORY_OPTS ? 'CHECKED' : '')?>> <a href=# class="info"><?php echo _("Play extension number")?><span><?php echo _("Plays a message \"Please hold while I transfer you to extension xxx\" that lets the caller know what extension to use in the future.")?></span></a> <?php echo _("to caller before transferring call")?><br><br>
+	<a href=# class="info"><?php echo _("Operator Extension:")?><span>
+	<?php echo _("When users hit '0' in the directory, they are put through to this number. Note that it"); ?>
+	<?php echo _(" does NOT need to be an extension, it can be a Ring Group, or even an external number."); ?></span></a>
+	<input type="text" size="10" name="OPERATOR_XTN" value="<?php  echo htmlspecialchars($OPERATOR_XTN)?>"/>
+</p>
+<h5><?php echo _("Fax Machine")?></h5>
+<p>
+	<?php echo _("Extension of")?> <a class="info" href="#"><?php echo _("fax machine")?><span><?php echo _("Select 'system' to have the system receive and email faxes.<br>Selecting 'disabled' will result in incoming calls being answered more quickly.")?></span></a> <?php echo _("for receiving faxes:")?>
+	<!--<input type="text" size="8" name="FAX_RX" value="<?php  echo $FAX_RX?>"/>-->
+	<select name="FAX_RX">
+		<option value="disabled" <?php  echo ($FAX_RX == 'disabled' ? 'SELECTED' : '')?>><?php echo _("disabled")?>
+		<option value="system" <?php  echo ($FAX_RX == 'system' ? 'SELECTED' : '')?>><?php echo _("system")?>
+<?php 
+	//get unique devices
+	$devices = core_devices_list();
+	if (isset($devices)) {
+		foreach ($devices as $device) {
+			echo '<option value="'.$device[0].'" '.($FAX_RX == $device[0] ? 'SELECTED' : '').'>'.$device[1].' &lt;'.$device[0].'&gt;';
+		}
+	}
+?>	
+	</select>
+	
+</p>
+<p>
+	<a class="info" href="#"><?php echo _("Email address")?><span><?php echo _("Email address used if 'system' has been chosen for the fax extension above.")?></span></a> <?php echo _("to have faxes emailed to:")?>
+	<input type="text" size="20" name="FAX_RX_EMAIL" value="<?php  echo htmlspecialchars($FAX_RX_EMAIL)?>"/>
+</p>
+<p>
+	<a class="info" href="#"><?php echo _("Email address")?><span><?php echo _("Email address that faxes appear to come from if 'system' has been chosen for the fax extension above.")?></span></a> <?php echo _("that faxes appear to come from:")?>
+	<input type="text" size="20" name="FAX_RX_FROM" value="<?php  echo htmlspecialchars($FAX_RX_FROM)?>"/>
+</p>
+<h5><?php echo _("International Settings")?></h5>
+<p>
+	<?php echo _("Country")?> <a class="info" href="#"><?php echo _("Indications")?><span><?php echo _("Select which country you are in")?></span></a>&nbsp;
+	<?php 	if (isset($TONEZONE) && strlen($TONEZONE)) 
+		general_display_zones($TONEZONE); 
+		else
+		general_display_zones('us'); 
+		?>
+</p>
+<p>
+	<a class="info" href="#"><?php echo _("24-hour format")?><span><?php echo _("Select Yes if you use 24-hour format or No if you are using 12-hour am/pm format")?></span></a>&nbsp;
+	<select name="TIMEFORMAT">
+		<option value="IMp"><?php echo _("no"); ?></option>
+		<option value="kM" <?php echo (($TIMEFORMAT=="kM") ? 'selected="selected"' : '');?>><?php echo _("yes"); ?></option>
+	</select>
+</p>
+<h5><?php echo _("Security Settings")?></h5>
+<p>
+	<a href=# class="info"><?php echo _("Allow Anonymous Inbound SIP Calls?")?><span><br>
+<?php echo _("** WARNING **")?><br><br>
+<?php echo _("Setting this to 'yes' will potentially allow ANYBODY to call into your Asterisk server using the SIP protocol")?><br><br>
+<?php echo _("It should only be used if you fully understand the impact of allowing anonymous calls into your server")?><br>
+	</span></a>&nbsp;
+	<select name="ALLOW_SIP_ANON">
+	<option value="no"><?php echo _("no"); ?></option>
+	<option <?php if ($ALLOW_SIP_ANON == "yes") echo "SELECTED "?>value="yes"><?php echo _("yes"); ?></option>
+	</select>
+</p>
+
+<h5><?php echo _("Online Updates")?></h5>
+	<table>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Check for Updates")?><span>
+			<?php echo _("Choosing Yes will result in the system automatically checking for updates nighly. The resuling infomation will be displayed in the dashboard and will be optionally emailed to the address below if provided.<br />This will trasmit your FreePBX and Asterisk version numbers along with a unique but random identifier. This is used to provide proper update information and to track version usage to focus development and maintenance efforts. No private information is trasmitted."); ?></span></a>
+			</td>
+			<td align=right>
+			<select name="online_updates">
+				<option value="yes"  <?php  echo ($online_updates == 'yes' ? 'SELECTED' : '')?>><?php echo _("Yes")?>
+				<option value="no"   <?php  echo ($online_updates == 'no'  ? 'SELECTED' : '')?>><?php echo _("No")?>
+			</select> 
+			</td>
+		</tr>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Update Email")?><span>
+			<?php echo _("Email address where online udpates will be sent. Leaving blank will result in no udpates being sent."); ?></span></a>
+			</td>
+			<td>
+				<input type="text" size="40" name="update_email" value="<?php  echo htmlspecialchars($update_email)?>"/>
+			</td>
+		</tr>
+	</table>
+<h6>
+	<input name="Submit" type="submit" value="<?php echo _("Submit Changes")?>">
+</h6>
+<script language="javascript">
+<!--
+
+var theForm = document.general;
+
+function hasRing (s) {
+	if (s.indexOf('r') >= 0) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+function warnConfirm (theField, s) {
+    theField.focus();
+    theField.select();
+		return confirm(s);
+}
+
+function general_onsubmit() {
+	var msgInvalidSeconds = "<?php echo _('Please enter a valid Number of Seconds'); ?>";
+	var msgInvalidDefaultFaxEmail = "<?php echo _('Please enter a valid Fax Email'); ?>";
+	var msgRingOptionOutboundTrunk = "<?php echo _('You have selected the \'r\' option for your trunks. This is highly discouraged and will create problems with calls on many PRI, VoIP, ISDN and other trunks that are capable of signalling. Asterisk will generate a ringing tone until the signalling indicates the line is answered. This will result in some external IVRs being inaccessible and other strange problems.'); ?>";
+
+	defaultEmptyOK = false;
+	if (!isInteger(theForm.RINGTIMER.value))
+		return warnInvalid(theForm.RINGTIMER, msgInvalidSeconds);
+
+	// Fax email must be present if selected 'system', otherwise optional
+	if (theForm.FAX_RX.value == "system") {
+		defaultEmptyOK = false;
+	} else {
+		defaultEmptyOK = true;
+	}
+	if (!isEmail(theForm.FAX_RX_EMAIL.value))
+		return warnInvalid(theForm.FAX_RX_EMAIL, msgInvalidDefaultFaxEmail);
+
+	if (hasRing(theForm.TRUNK_OPTIONS.value))
+		return warnConfirm(theForm.TRUNK_OPTIONS, msgRingOptionOutboundTrunk);
+	
+	return true;
+}
+
+//-->
+</script>
+</form>
+

Added: freepbx-modules/trunk/modules/core/page.routing.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/page.routing.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/page.routing.php (added)
+++ freepbx-modules/trunk/modules/core/page.routing.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,675 @@
+<?php /* $Id: page.routing.php 5576 2008-01-12 19:12:26Z p_lindheimer $ */
+// routing.php Copyright (C) 2004 Greg MacLellan (greg at mtechsolutions.ca)
+// routing.php <trunk & roting priority additions> Copyright (C) 2005 Ron Hartmann (rhartmann at vercomsystems.com)
+// Asterisk Management Portal Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+$display='routing'; 
+$extdisplay=isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:'';
+$action = isset($_REQUEST['action'])?$_REQUEST['action']:'';
+
+$repotrunkdirection = isset($_REQUEST['repotrunkdirection'])?$_REQUEST['repotrunkdirection']:'';
+$repotrunkkey = isset($_REQUEST['repotrunkkey'])?$_REQUEST['repotrunkkey']:'';
+
+
+$dialpattern = array();
+if (isset($_REQUEST["dialpattern"])) {
+	//$dialpattern = $_REQUEST["dialpattern"];
+	$dialpattern = explode("\n",$_REQUEST["dialpattern"]);
+
+	if (!$dialpattern) {
+		$dialpattern = array();
+	}
+	
+	foreach (array_keys($dialpattern) as $key) {
+		//trim it
+		$dialpattern[$key] = trim($dialpattern[$key]);
+		
+		// remove blanks
+		if ($dialpattern[$key] == "") unset($dialpattern[$key]);
+		
+		// remove leading underscores (we do that on backend)
+		if ($dialpattern[$key][0] == "_") $dialpattern[$key] = substr($dialpattern[$key],1);
+	}
+	
+	// check for duplicates, and re-sequence
+	$dialpattern = array_values(array_unique($dialpattern));
+}
+	
+if ( (isset($_REQUEST['reporoutedirection'])) && (isset($_REQUEST['reporoutekey']))) {
+	$routepriority = core_routing_getroutenames();
+	$routepriority = core_routing_setroutepriority($routepriority, $_REQUEST['reporoutedirection'], $_REQUEST['reporoutekey']);
+}
+
+$trunkpriority = array();
+if (isset($_REQUEST["trunkpriority"])) {
+	$trunkpriority = $_REQUEST["trunkpriority"];
+
+	if (!$trunkpriority) {
+		$trunkpriority = array();
+	}
+	
+	// delete blank entries and reorder
+	foreach (array_keys($trunkpriority) as $key) {
+		if (empty($trunkpriority[$key])) {
+			// delete this empty
+			unset($trunkpriority[$key]);
+			
+		} else if (($key==($repotrunkkey-1)) && ($repotrunkdirection=="up")) {
+			// swap this one with the one before (move up)
+			$temptrunk = $trunkpriority[$key];
+			$trunkpriority[ $key ] = $trunkpriority[ $key+1 ];
+			$trunkpriority[ $key+1 ] = $temptrunk;
+			
+		} else if (($key==($repotrunkkey)) && ($repotrunkdirection=="down")) {
+			// swap this one with the one after (move down)
+			$temptrunk = $trunkpriority[ $key+1 ];
+			$trunkpriority[ $key+1 ] = $trunkpriority[ $key ];
+			$trunkpriority[ $key ] = $temptrunk;
+		}
+	}
+	unset($temptrunk);
+	$trunkpriority = array_values($trunkpriority); // resequence our numbers
+}
+
+$routename = isset($_REQUEST["routename"]) ? $_REQUEST["routename"] : "";
+$routepass = isset($_REQUEST["routepass"]) ? $_REQUEST["routepass"] : "";
+$emergency = isset($_REQUEST["emergency"]) ? $_REQUEST["emergency"] : "";
+$intracompany = isset($_REQUEST["intracompany"]) ? $_REQUEST["intracompany"] : "";
+$mohsilence = isset($_REQUEST["mohsilence"]) ? $_REQUEST["mohsilence"] : "";
+
+//if submitting form, update database
+switch ($action) {
+	case "addroute":
+		core_routing_add($routename, $dialpattern, $trunkpriority,"new", $routepass, $emergency, $intracompany, $mohsilence);
+		needreload();
+		redirect_standard();
+	break;
+	case "editroute":
+		core_routing_edit($routename, $dialpattern, $trunkpriority, $routepass, $emergency, $intracompany, $mohsilence);
+		needreload();
+		redirect_standard('extdisplay');
+	break;
+	case "delroute":
+		core_routing_del($extdisplay);
+		// re-order the routes to make sure that there are no skipped numbers.
+		// example if we have 001-test1, 002-test2, and 003-test3 then delete 002-test2
+		// we do not want to have our routes as 001-test1, 003-test3 we need to reorder them
+		// so we are left with 001-test1, 002-test3
+		$routepriority = core_routing_getroutenames();
+		$routepriority = core_routing_setroutepriority($routepriority, '','');
+		needreload();
+		redirect_standard();
+	break;
+	case 'renameroute':
+		if (core_routing_rename($routename, $_REQUEST["newroutename"])) {
+			needreload();
+		} else {
+			echo "<script language=\"javascript\">alert('"._("Error renaming route: duplicate name")."');</script>";
+		}
+		$route_prefix=substr($routename,0,4);
+		$extdisplay=$route_prefix.$_REQUEST["newroutename"];
+
+	break;
+	case 'prioritizeroute':
+		needreload();
+	break;
+	case 'populatenpanxx':
+		if (preg_match("/^([2-9]\d\d)-?([2-9]\d\d)$/", $_REQUEST["npanxx"], $matches)) {
+			// first thing we do is grab the exch:
+			$ch = curl_init();
+			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+			curl_setopt($ch, CURLOPT_URL, "http://www.localcallingguide.com/xmllocalprefix.php?npa=".$matches[1]."&nxx=".$matches[2]);
+			curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Linux; FreePBX Local Trunks Configuration)");
+			$str = curl_exec($ch);
+			curl_close($ch);
+
+			// quick 'n dirty - nabbed from PEAR
+			require_once($amp_conf['AMPWEBROOT'] . '/admin/modules/core/XML_Parser.php');
+			require_once($amp_conf['AMPWEBROOT'] . '/admin/modules/core/XML_Unserializer.php');
+
+			$xml = new xml_unserializer;
+			$xml->unserialize($str);
+			$xmldata = $xml->getUnserializedData();
+
+			if (isset($xmldata['lca-data']['prefix'])) {
+				// we do the loops separately so patterns are grouped together
+				
+				// match 1+NPA+NXX (dropping 1)
+				foreach ($xmldata['lca-data']['prefix'] as $prefix) {
+					$dialpattern[] = '1|'.$prefix['npa'].$prefix['nxx'].'XXXX';
+				}
+				// match NPA+NXX
+				foreach ($xmldata['lca-data']['prefix'] as $prefix) {
+					$dialpattern[] = $prefix['npa'].$prefix['nxx'].'XXXX';
+				}
+				// match 7-digits
+				foreach ($xmldata['lca-data']['prefix'] as $prefix) {
+					$dialpattern[] = $prefix['nxx'].'XXXX';
+				}
+
+				// check for duplicates, and re-sequence
+				$dialpattern = array_values(array_unique($dialpattern));
+			} else {
+				$errormsg = _("Error fetching prefix list for: "). $_REQUEST["npanxx"];
+			}
+			
+		} else {
+			// what a horrible error message... :p
+			$errormsg = _("Invalid format for NPA-NXX code (must be format: NXXNXX)");
+		}
+		
+		if (isset($errormsg)) {
+			echo "<script language=\"javascript\">alert('".addslashes($errormsg)."');</script>";
+			unset($errormsg);
+		}
+	break;
+}
+	
+
+	
+//get all rows from globals
+$sql = "SELECT * FROM globals";
+$globals = $db->getAll($sql);
+if(DB::IsError($globals)) {
+die_freepbx($globals->getMessage());
+}
+
+//create a set of variables that match the items in global[0]
+foreach ($globals as $global) {
+	${trim($global[0])} = htmlentities($global[1]);	
+}
+
+?>
+</div>
+
+
+
+<div class="rnav">
+<ul>
+	<li><a <?php  echo ($extdisplay=='' ? 'class="current"':'') ?> href="config.php?display=<?php echo urlencode($display)?>"><?php echo _("Add Route")?></a></li>
+<?php 
+$reporoutedirection = isset($_REQUEST['reporoutedirection'])?$_REQUEST['reporoutedirection']:'';
+$reporoutekey = isset($_REQUEST['reporoutekey'])?$_REQUEST['reporoutekey']:'';
+$key = -1;
+$routepriority = core_routing_getroutenames();
+$positions=count($routepriority);
+foreach ($routepriority as $tresult) {
+	$key++;
+		echo "\t<li>\n\t\t<a " . ($extdisplay==$tresult[0] ? 'class="current"':'') .
+			" href=\"config.php?display=" . 
+			urlencode($display)."&amp;extdisplay=" . 
+			urlencode($tresult[0]) . "\">$key " . substr($tresult[0],4)."</a>\n";
+
+		if ($key > 0)
+			echo "\t\t<img src=\"images/scrollup.gif\" onclick=\"repositionRoute('$key','up')\" alt='" .  _("Move Up") .
+				"' style='float:none; margin-left:0px; margin-bottom:0px;' width='9' height='11'>\n";
+		else
+			echo "\t\t<img src='images/blank.gif' style='float:none; margin-left:0px; margin-bottom:0px;' width='9' height='11'>\n";
+
+		// move down
+		if ($key < ($positions-1))
+			echo "\t\t<img src='images/scrolldown.gif' onclick=\"repositionRoute('$key>','down')\" alt='" . _("Move Down") .
+				"'  style='float:none; margin-left:0px; margin-bottom:0px;' width='9' height='11'>\n";
+		else 
+			echo "\t\t<img src='images/blank.gif' style='loat:none; margin-left:0px; margin-bottom:0px;' width='9' height='11'>\n";
+			echo "\t</li>\n";
+} // foreach
+?>
+</ul>
+</div>
+
+<div class="content">
+
+<?php 
+if ($extdisplay) {
+	
+	// load from db
+	
+	if (!isset($_REQUEST["dialpattern"])) {
+		$dialpattern = core_routing_getroutepatterns($extdisplay);
+	}
+	
+	if (!isset($_REQUEST["trunkpriority"])) {
+		$trunkpriority = core_routing_getroutetrunks($extdisplay);
+	}
+	
+	if (!isset($_REQUEST["routepass"])) {
+		$routepass = core_routing_getroutepassword($extdisplay);
+	}
+	
+	if (!isset($_REQUEST["emergency"])) {
+		$emergency = core_routing_getrouteemergency($extdisplay);
+	}
+	
+	if (!isset($_REQUEST["intracompany"])) {
+		$intracompany = core_routing_getrouteintracompany($extdisplay);
+	}
+
+	if (!isset($_REQUEST["mohsilence"])) {
+		$mohsilence = core_routing_getroutemohsilence($extdisplay);
+	}
+	
+	echo "<h2>"._("Edit Route")."</h2>";
+} else {	
+	echo "<h2>"._("Add Route")."</h2>";
+}
+
+// build trunks associative array
+foreach (core_trunks_list() as $temp) {
+	$trunks[$temp[0]] = $temp[1];
+	$trunkstate[$temp[0]] = $temp[2];
+}
+
+if ($extdisplay) { // editing
+?>
+	<p><a href="config.php?display=<?php echo urlencode($display) ?>&extdisplay=<?php echo urlencode($extdisplay) ?>&action=delroute"><?php echo _("Delete Route")?> <?php  echo substr($extdisplay,4); ?></a></p>
+<?php  } ?>
+
+	<form autocomplete="off" id="routeEdit" name="routeEdit" action="config.php" method="POST" onsubmit="return routeEdit_onsubmit('<?php echo ($extdisplay ? "editroute" : "addroute") ?>');">
+		<input type="hidden" name="display" value="<?php echo $display?>"/>
+		<input type="hidden" name="extdisplay" value="<?php echo $extdisplay ?>"/>
+		<input type="hidden" id="action" name="action" value=""/>
+		<table>
+		<tr>
+			<td>
+				<a href=# class="info"><?php echo _("Route Name")?><span><br><?php echo _("Name of this route. Should be used to describe what type of calls this route matches (for example, 'local' or 'longdistance').")?><br><br></span></a>: 
+			</td>
+<?php  if ($extdisplay) { // editing?>
+			<td>
+				<?php echo substr($extdisplay,4);?>
+				<input type="hidden" id="routename" name="routename" value="<?php echo $extdisplay;?>"/>
+				<input type="button" onClick="renameRoute();" value="<?php echo _("Rename")?>" style="font-size:10px;"  />
+				<input type="hidden" id="newroutename" name="newroutename" value=""/>
+				<script language="javascript">
+				function renameRoute() {
+					do {
+						var newname = prompt("<?php echo _("Rename route")?> " + document.getElementById('routename').value + " <?php echo _("to:")?>");
+						if (newname == null) return;
+					} while (!newname.match('^[a-zA-Z0-9][a-zA-Z0-9_]+$') && !alert("<?php echo _("Route name is invalid...please try again")?>"));
+					
+					document.getElementById('newroutename').value = newname;
+					document.getElementById('routeEdit').action.value = 'renameroute';
+					document.getElementById('routeEdit').submit();
+				}
+				</script>
+			</td>
+<?php  } else { // new ?>
+			<td>
+				<input type="text" size="20" name="routename" value="<?php echo htmlspecialchars($routename);?>"/>
+			</td>
+<?php  } ?>
+		</tr>
+		<tr>
+			<td><a href=# class="info"><?php echo _("Route Password")?>:<span><?php echo _("Optional: A route can prompt users for a password before allowing calls to progress.  This is useful for restricting calls to international destinations or 1-900 numbers.<br><br>A numerical password, or the path to an Authenticate password file can be used.<br><br>Leave this field blank to not prompt for password.</span>")?></a></td>
+			<td><input type="text" size="20" name="routepass" value="<?php echo $routepass;?>"/></td>
+		</tr>
+<?php
+	// implementation of module hook
+	// object was initialized in config.php
+	echo $module_hook->hookHtml;
+?>
+		<tr>
+			<td><a href=# class="info"><?php echo _("Emergency Dialing")?><span><?php echo _("Optional: Selecting this option will enforce the use of a device's Emergency CID setting (if set).  Select this option if this set of routes is used for emergency dialing (ie: 911).</span>")?></a>:</td>
+			<td><input type="checkbox" name="emergency" value="yes" <?php echo ($emergency ? "CHECKED" : "") ?> /></td>
+		</tr>
+		<tr>
+			<td><a href=# class="info"><?php echo _("Intra Company Route")?><span><?php echo _("Optional: Selecting this option will treat this route as a intra-company connection, preserving the internal Caller ID information and not use the outbound CID of either the extension or trunk.</span>")?></a>:</td>
+			<td><input type="checkbox" name="intracompany" value="yes" <?php echo ($intracompany ? "CHECKED" : "") ?> /></td>
+		</tr>
+<?php   if (function_exists('music_list')) { ?>
+		<tr>
+			<td><a href="#" class="info"><?php echo _("Music On Hold?")?><span><?php echo _("You can choose which music category to use. For example, choose a type appropriate for a destination country which may have announcements in the appropriate language.")?></span></a></td>
+			<td>
+				&nbsp;&nbsp;<select name="mohsilence"/>
+				<?php
+					$tresults = music_list($amp_conf['ASTVARLIBDIR']."/mohmp3");
+					$cur = (isset($mohsilence) && $mohsilence != "" ? $mohsilence : 'default');
+					if (isset($tresults[0])) {
+						foreach ($tresults as $tresult) {
+							echo '<option value="'.$tresult.'"'.($tresult == $cur ? ' SELECTED' : '').'>'.$tresult."</option>\n";
+						}
+					}
+				?>		
+				</select>		
+			</td>
+		</tr>
+<?php } ?>
+		<tr>
+			<td colspan="2">
+				<br>
+				<a href=# class="info"><?php echo _("Dial Patterns")?><span><?php echo _("A Dial Pattern is a unique set of digits that will select this trunk. Enter one dial pattern per line.")?><br><br><b><?php echo _("Rules:")?></b><br>
+   <strong>X</strong>&nbsp;&nbsp;&nbsp; <?php echo _("matches any digit from 0-9")?><br>
+   <strong>Z</strong>&nbsp;&nbsp;&nbsp; <?php echo _("matches any digit from 1-9")?><br>
+   <strong>N</strong>&nbsp;&nbsp;&nbsp; <?php echo _("matches any digit from 2-9")?><br>
+   <strong>[1237-9]</strong>&nbsp;   <?php echo _("matches any digit or letter in the brackets (in this example, 1,2,3,7,8,9)")?><br>
+   <strong>.</strong>&nbsp;&nbsp;&nbsp; <?php echo _("wildcard, matches one or more characters")?> <br>
+   <strong>|</strong>&nbsp;&nbsp;&nbsp; <?php echo _("seperates a dialing prefix from the number (for example, 9|NXXXXXX would match when some dialed \"95551234\" but would only pass \"5551234\" to the trunks)")?>
+				</span></a><br><br>
+			</td>
+		</tr>
+<?php  /* old code for using textboxes -- replaced by textarea code
+$key = -1;
+foreach ($dialpattern as $key=>$pattern) {
+?>
+		<tr>
+			<td><?php echo $key ?>
+			</td><td>
+				<input type="text" size="20" name="dialpattern[<?php echo $key ?>]" value="<?php echo $dialpattern[$key] ?>"/>
+			</td>
+		</tr>
+<?php 
+} // foreach
+
+$key += 1; // this will be the next key value
+?>
+		<tr>
+			<td><?php echo $key ?>
+			</td><td>
+				<input type="text" size="20" name="dialpattern[<?php echo $key ?>]" value="<?php echo $dialpattern[$key] ?>"/>
+			</td>
+		</tr>
+		<tr>
+			<td>&nbsp;</td>
+			<td>
+				<br><input type="submit" value="<?php echo _("Add"); ?>">
+			</td>
+		</tr>
+<?php  */ ?>
+		<tr>
+			<td>
+			</td><td>
+				<textarea cols="20" rows="<?php  $rows = count($dialpattern)+1; echo (($rows < 5) ? 5 : (($rows > 20) ? 20 : $rows) ); ?>" id="dialpattern" name="dialpattern"><?php echo  implode("\n",$dialpattern);?></textarea><br>
+				
+				<input type="submit" style="font-size:10px;" value="<?php echo _("Clean & Remove duplicates")?>" />
+			</td>
+		</tr>
+		<tr>
+			<td>
+			<a href=# class="info"><?php echo _("Dial patterns wizards")?><span>
+					<strong><?php echo _("These options provide a quick way to add outbound dialing rules. Follow the prompts for each.")?><br>
+					<strong><?php echo _("Lookup local prefixes")?></strong> <?php echo _("This looks up your local number on www.localcallingguide.com (NA-only), and sets up so you can dial either 7, 10 or 11 digits (5551234, 6135551234, 16135551234) to access this route.")?><br>
+					</span></a>:
+			<input id="npanxx" name="npanxx" type="hidden" />
+			<script language="javascript">
+			
+			function populateLookup() {
+<?php 
+	if (function_exists("curl_init")) { // curl is installed
+?>				
+				//var npanxx = prompt("What is your areacode + prefix (NPA-NXX)?", document.getElementById('areacode').value);
+				do {
+					var npanxx = <?php echo 'prompt("'._("What is your areacode + prefix (NPA-NXX)?\\n\\n(Note: this database contains North American numbers only, and is not guaranteed to be 100% accurate. You will still have the option of modifying results.)\\n\\nThis may take a few seconds.").'")' ?>;
+					if (npanxx == null) return;
+				} while (!npanxx.match("^[2-9][0-9][0-9][-]?[2-9][0-9][0-9]$") && <?php echo '!alert("'._("Invalid NPA-NXX. Must be of the format \'NXX-NXX\'").'")'?>);
+				
+				document.getElementById('npanxx').value = npanxx;
+				document.getElementById('routeEdit').action.value = "populatenpanxx";
+				document.getElementById('routeEdit').submit();
+<?php  
+	} else { // curl is not installed
+?>
+				<?php echo "alert('"._("Error: Cannot continue!\\n\\nPrefix lookup requires cURL support in PHP on the server. Please install or enable cURL support in your PHP installation to use this function. See http://www.php.net/curl for more information.")."')"?>;
+<?php 
+	}
+?>
+			}
+			
+						
+			function insertCode() {
+				code = document.getElementById('inscode').value;
+				insert = '';
+				switch(code) {
+					case "local":
+						insert = 'NXXXXXX\n';
+					break;
+					case "local10":
+						insert = 'NXXXXXX\n'+
+							'NXXNXXXXXX\n';
+					break;
+					case 'tollfree':
+						insert = '1800NXXXXXX\n'+
+							'1888NXXXXXX\n'+
+							'1877NXXXXXX\n'+
+							'1866NXXXXXX\n';
+					break;
+					case "ld":
+						insert = '1NXXNXXXXXX\n';
+					break;
+					case "int":
+						insert = '011.\n';
+					break;
+					case 'info':
+						insert = '411\n'+
+							'311\n';
+					break;
+					case 'emerg':
+						insert = '911\n';
+					break;
+					case 'lookup':
+						populateLookup();
+						insert = '';
+					break;
+					
+				}
+				dialPattern=document.getElementById('dialpattern');
+				if (dialPattern.value[ dialPattern.value.length - 1 ] == "\n") {
+					dialPattern.value = dialPattern.value + insert;
+				} else {
+					dialPattern.value = dialPattern.value + '\n' + insert;
+				}
+				
+				// reset element
+				document.getElementById('inscode').value = '';
+			}
+			
+			--></script>
+			<td>
+				<select onChange="insertCode();" id="inscode">
+			<option value=""><?php echo _("(pick one)")?></option>
+			<option value="local"><?php echo _("Local 7 digit")?></option>
+			<option value="local10"><?php echo _("Local 7/10 digit")?></option>
+			<option value="tollfree"><?php echo _("Toll-free")?></option>
+			<option value="ld"><?php echo _("Long-distance")?></option>
+			<option value="int"><?php echo _("International")?></option>
+			<option value="info"><?php echo _("Information")?></option>
+			<option value="emerg"><?php echo _("Emergency")?></option>
+			<option value="lookup"><?php echo _("Lookup local prefixes")?></option>
+				</select>
+			</td>
+		</tr>
+		<tr>
+			<td colspan="2">
+			<br><br>
+				<a href=# class="info"><?php echo _("Trunk Sequence")?><span><?php echo _("The Trunk Sequence controls the order of trunks that will be used when the above Dial Patterns are matched. <br><br>For Dial Patterns that match long distance numbers, for example, you'd want to pick the cheapest routes for long distance (ie, VoIP trunks first) followed by more expensive routes (POTS lines).")?><br></span></a><br><br>
+			</td>
+		</tr>
+		<input type="hidden" id="repotrunkdirection" name="repotrunkdirection" value="">
+		<input type="hidden" id="repotrunkkey" name="repotrunkkey" value="">
+		<input type="hidden" id="reporoutedirection" name="reporoutedirection" value="">
+		<input type="hidden" id="reporoutekey" name="reporoutekey" value="">
+<?php 
+$key = -1;
+$positions=count($trunkpriority);
+foreach ($trunkpriority as $key=>$trunk) {
+?>
+		<tr>
+			<td align="right"><?php echo $key; ?>&nbsp;&nbsp;
+			</td>
+			<td>
+		<select id='trunkpri<?php echo $key ?>' name="trunkpriority[<?php echo $key ?>]" style="background: <?php echo $trunkstate[$trunk]=="off"?"#FFF":"#DDD" ?> ;" onChange="showDisable(<?php echo $key ?>); return true;">
+				<option value="" style="background: #FFF;"></option>
+				<?php 
+				foreach ($trunks as $name=>$display_description) {
+					if ($trunkstate[$name] == 'off') {
+						echo "<option id=\"trunk".$key."\" name=\"trunk".$key."\" value=\"".$name."\" style=\"background: #FFF;\" ".($name == $trunk ? "selected" : "").">".str_replace('AMP:', '', $display_description)."</option>";
+					} else {
+						echo "<option id=\"trunk".$key."\" name=\"trunk".$key."\" value=\"".$name."\" style=\"background: #DDD;\" ".($name == $trunk ? "selected" : "").">".str_replace('AMP:', '', $display_description)."</option>";
+					}
+				}
+				?>
+				</select>
+				
+				<img src="images/trash.png" style="float:none; margin-left:0px; margin-bottom:0px;" title="Click here to remove this trunk" onclick="deleteTrunk(<?php echo $key ?>)">
+			<?php   // move up
+			if ($key > 0) {?>
+				<img src="images/scrollup.gif" onclick="repositionTrunk('<?php echo $key ?>','up')" alt="<?php echo _("Move Up")?>" style="float:none; margin-left:0px; margin-bottom:0px;" width="9" height="11">
+			<?php  } else { ?>
+				<img src="images/blank.gif" style="float:none; margin-left:0px; margin-bottom:0px;" width="9" height="11">
+			<?php  }
+			
+			// move down
+			
+			if ($key < ($positions-1)) {?>
+				<img src="images/scrolldown.gif" onclick="repositionTrunk('<?php echo $key ?>','down')" alt="<?php echo _("Move Down")?>"  style="float:none; margin-left:0px; margin-bottom:0px;" width="9" height="11">
+			<?php  } else { ?>
+				<img src="images/blank.gif" style="float:none; margin-left:0px; margin-bottom:0px;" width="9" height="11">
+			<?php  } ?>
+			</td>
+		</tr>
+<?php 
+} // foreach
+
+$key += 1; // this will be the next key value
+$name = "";
+
+// display 1 additional box if editing, or one for each trunk (to a max of 3)
+$num_new_boxes = ($extdisplay ? 1 : ((count($trunks) > 3) ? 3 : count($trunks)));
+
+for ($i=0; $i < $num_new_boxes; $i++) {
+?>
+		<tr>
+			<td> &nbsp </td>
+			<td>
+				<select id='trunkpri<?php echo $key ?>' name="trunkpriority[<?php echo $key ?>]">
+				<option value="" SELECTED></option>
+				<?php 
+				foreach ($trunks as $name=>$display_description) {
+					if ($trunkstate[$name] == 'off') {
+					echo "<option value=\"".$name."\">".str_replace('AMP:', '', $display_description)."</option>";
+					} else {
+					echo "<option value=\"".$name."\" style=\"background: #DDD;\" >*".ltrim($display_description,"AMP:")."*</option>";
+					}
+				}
+				?>
+				</select>
+			</td>
+		</tr>
+<?php 
+	$key++;
+} //for 0..$num_new_boxes ?>
+
+<?php if ($extdisplay): // editing ?>
+		<tr>
+			<td></td>
+			<td>
+				<input type="submit" value="<?php echo _("Add")?>">
+			</td>
+		</tr>
+<?php endif; // if $extdisplay ?>
+		<tr>
+			<td colspan="2">
+			<br>
+				<h6><input name="Submit" type="submit" value="<?php echo _("Submit Changes")?>">
+				</h6>
+			</td>
+		</tr>
+		</table>
+ 
+<script language="javascript">
+<!--
+
+var theForm = document.routeEdit;
+
+if (theForm.routename.value == "") {
+	theForm.routename.focus();
+} else {
+	theForm.routepass.focus();
+}
+
+function showDisable(key) {
+<?php
+	$bgmap = 'bgc = {';
+	foreach ($trunks as $name=>$display_description) {
+		$bgmap .= " \"$name\":";
+		$bgmap .= ($trunkstate[$name] == 'off')?'"#FFF",':'"#DDD",';
+	}
+	echo rtrim($bgmap,',')." };\n";
+?>
+	if (document.getElementById('trunkpri'+key).value =='') {
+		document.getElementById('trunkpri'+key).style.background = '#FFF';
+	} else {
+		document.getElementById('trunkpri'+key).style.background = bgc[document.getElementById('trunkpri'+key).value];
+	}
+}
+
+function routeEdit_onsubmit(act) {
+	var msgInvalidRouteName = "<?php echo _('Route name is invalid, please try again'); ?>";
+	var msgInvalidRoutePwd = "<?php echo _('Route password must be numberic or leave blank to disable'); ?>";
+	var msgInvalidDialPattern = "<?php echo _('Dial pattern is invalid'); ?>";
+	var msgInvalidTrunkSelection = "<?php echo _('At least one trunk must be picked'); ?>";
+	
+	defaultEmptyOK = false;
+	if (isEmpty(theForm.routename.value))
+		return warnInvalid(theForm.routename, msgInvalidRouteName);
+	
+	defaultEmptyOK = true;
+	if (!isInteger(theForm.routepass.value))
+		return warnInvalid(theForm.routepass, msgInvalidRoutePwd);
+	
+	defaultEmptyOK = false;
+	if (!isDialpattern(theForm.dialpattern.value))
+		return warnInvalid(theForm.dialpattern, msgInvalidDialPattern);
+		
+	if (theForm.trunkpri0.value == "") { // should they all be checked ?
+		theForm.trunkpri0.focus();
+		alert(msgInvalidTrunkSelection);
+		return false;
+	}
+	
+	theForm.action.value = act;
+	return true;
+}
+
+function repositionTrunk(key,direction) {
+	if(direction == "up"){
+		document.getElementById('repotrunkdirection').value=direction;
+		document.getElementById('repotrunkkey').value=key;
+	}else if(direction == "down" ){
+		document.getElementById('repotrunkdirection').value=direction;
+		document.getElementById('repotrunkkey').value=key;
+	}
+	document.getElementById('routeEdit').submit();
+}
+
+function deleteTrunk(key) {
+	document.getElementById('trunkpri'+key).value = '';
+	document.getElementById('routeEdit').submit();
+}
+
+function repositionRoute(key,direction){
+	if(direction == "up"){
+		document.getElementById('reporoutedirection').value=direction;
+		document.getElementById('reporoutekey').value=key;
+	}else if(direction == "down" ){
+		document.getElementById('reporoutedirection').value=direction;
+		document.getElementById('reporoutekey').value=key;
+	}
+	document.getElementById('action').value='prioritizeroute';
+	document.getElementById('routeEdit').submit();
+}
+
+//-->
+</script>
+
+</form>
+

Added: freepbx-modules/trunk/modules/core/page.trunks.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/page.trunks.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/page.trunks.php (added)
+++ freepbx-modules/trunk/modules/core/page.trunks.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,822 @@
+<?php /* $Id: page.trunks.php 5576 2008-01-12 19:12:26Z p_lindheimer $ */
+// routing.php Copyright (C) 2004 Greg MacLellan (greg at mtechsolutions.ca)
+// Asterisk Management Portal Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+
+
+$display='trunks'; 
+$extdisplay=isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:'';
+$action = isset($_REQUEST['action'])?$_REQUEST['action']:'';
+$tech = strtolower(isset($_REQUEST['tech'])?$_REQUEST['tech']:'');
+
+$trunknum = ltrim($extdisplay,'OUT_');
+
+
+// populate some global variables from the request string
+$set_globals = array("outcid","maxchans","dialoutprefix","channelid","peerdetails","usercontext","userconfig","register","keepcid","failtrunk","disabletrunk");
+foreach ($set_globals as $var) {
+	if (isset($_REQUEST[$var])) {
+		$$var = stripslashes( $_REQUEST[$var] );
+	}
+}
+
+// ensure that keepcid is set to something:
+if (!isset($keepcid)) {
+	$keepcid = "off";
+}
+// ensure that failtrunk is set to something:
+if (!isset($failtrunk)) {
+	$failtrunk = "";
+}
+$failtrunk_enable = ($failtrunk == "")?'':'CHECKED';
+
+if (!isset($disabletrunk)) {
+	$disabletrunk = "off";
+}
+
+if (isset($_REQUEST["dialrules"])) {
+	//$dialpattern = $_REQUEST["dialpattern"];
+	$dialrules = explode("\n",$_REQUEST["dialrules"]);
+
+	if (is_array($dialrules))
+		foreach (array_keys($dialrules) as $key) {
+			//trim it
+			$dialrules[$key] = trim($dialrules[$key]);
+			
+			// remove blanks
+			if ($dialrules[$key] == "") unset($dialrules[$key]);
+			
+			// remove leading underscores (we do that on backend)
+			if ($dialrules[$key][0] == "_") $dialrules[$key] = substr($dialrules[$key],1);
+		}
+	
+	// check for duplicates, and re-sequence
+	$dialrules = array_values(array_unique($dialrules));
+} else {
+	$dialrules = array();
+}
+
+//if submitting form, update database
+switch ($action) {
+	case "addtrunk":
+		if (!isset($failtrunk))
+		    $failtrunk="";
+		$trunknum = core_trunks_add($tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register, $keepcid, trim($failtrunk),$disabletrunk);
+		
+		core_trunks_addDialRules($trunknum, $dialrules);
+		needreload();
+		redirect_standard();
+	break;
+	case "edittrunk":
+		if (!isset($failtrunk))
+		    $failtrunk="";
+		core_trunks_edit($trunknum, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register, $keepcid, trim($failtrunk), $disabletrunk);
+		
+		/* //DIALRULES
+		deleteTrunkRules($channelid);
+		addTrunkRules($channelid, $dialrules);
+		*/
+		
+		// this can rewrite too, so edit is the same
+		core_trunks_addDialRules($trunknum, $dialrules);
+		needreload();
+		redirect_standard('extdisplay');
+	break;
+	case "deltrunk":
+	
+		core_trunks_del($trunknum);
+		
+		/* //DIALRULES
+		deleteTrunkRules($channelid);
+		*/
+		core_trunks_deleteDialRules($trunknum);
+		needreload();
+		redirect_standard();
+	break;
+	case "populatenpanxx7": 
+	case "populatenpanxx10": 
+		if (preg_match("/^([2-9]\d\d)-?([2-9]\d\d)$/", $_REQUEST["npanxx"], $matches)) {
+			// first thing we do is grab the exch:
+			$ch = curl_init();
+			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+			curl_setopt($ch, CURLOPT_URL, "http://www.localcallingguide.com/xmllocalprefix.php?npa=".$matches[1]."&nxx=".$matches[2]);
+			curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Linux; FreePBX Local Trunks Configuration)");
+			$str = curl_exec($ch);
+			curl_close($ch);
+
+			// quick 'n dirty - nabbed from PEAR
+			require_once($amp_conf['AMPWEBROOT'] . '/admin/modules/core/XML_Parser.php');
+			require_once($amp_conf['AMPWEBROOT'] . '/admin/modules/core/XML_Unserializer.php');
+
+			$xml = new xml_unserializer;
+			$xml->unserialize($str);
+			$xmldata = $xml->getUnserializedData();
+
+			if (isset($xmldata['lca-data']['prefix'])) {
+				
+				if ($action == 'populatenpanxx10') {
+					// 10 digit dialing
+					// - add area code to 7 digits
+					// - match local 10 digits
+					// - add 1 to anything else
+					$dialrules[] = $matches[1].'NXXXXXX';
+					// add NPA to 7-digits
+					foreach ($xmldata['lca-data']['prefix'] as $prefix) {
+						$dialrules[] = $prefix['npa'].'+'.$prefix['nxx'].'XXXX';
+					}
+					foreach ($xmldata['lca-data']['prefix'] as $prefix) {
+						$dialrules[] = $prefix['npa'].$prefix['nxx'].'XXXX';
+					}
+					// if a number was not matched as local, dial it with '1' prefix
+					$dialrules[] = '1+NXXNXXXXXX';
+				} else {
+					// 7 digit dialing
+					// - drop area code from local numbers
+					// - match local 7 digit numbers
+					// - add 1 to everything else
+					foreach ($xmldata['lca-data']['prefix'] as $prefix) {
+						$dialrules[] = $prefix['npa'].'|'.$prefix['nxx'].'XXXX';
+					}
+					foreach ($xmldata['lca-data']['prefix'] as $prefix) {
+						$dialrules[] = $prefix['nxx'].'XXXX';
+					}
+					$dialrules[] = '1+NXXNXXXXXX';
+					$dialrules[] = '1'.$matches[1].'+NXXXXXX';
+				}
+
+				// check for duplicates, and re-sequence
+				$dialrules = array_values(array_unique($dialrules));
+			} else {
+				$errormsg = _("Error fetching prefix list for: "). $_REQUEST["npanxx"];
+			}
+
+		} else {
+			// what a horrible error message... :p
+			$errormsg = _("Invalid format for NPA-NXX code (must be format: NXXNXX)");
+		}
+		
+		if (isset($errormsg)) {
+			echo "<script language=\"javascript\">alert('".addslashes($errormsg)."');</script>";
+			unset($errormsg);
+		}
+	break;
+}
+	
+
+	
+//get all rows from globals
+$sql = "SELECT * FROM globals";
+$globals = $db->getAll($sql);
+if(DB::IsError($globals)) {
+	die_freepbx($globals->getMessage());
+}
+
+//create a set of variables that match the items in global[0]
+foreach ($globals as $global) {
+	${trim($global[0])} = htmlentities($global[1]);
+}
+
+?>
+</div>
+
+<div class="rnav">
+<ul>
+	<li><a <?php  echo ($extdisplay=='' ? 'class="current"':'') ?> href="config.php?display=<?php echo urlencode($display)?>"><?php echo _("Add Trunk")?></a></li>
+<?php 
+//get existing trunk info
+$tresults = core_trunks_list();
+
+foreach ($tresults as $tresult) {
+	$background = ($tresult[2] == 'on')?'#DDD':'#FFF';
+	echo "\t<li><a ".($extdisplay==$tresult[0] ? 'class="current"':'')." href=\"config.php?display=".urlencode($display)."&amp;extdisplay=".urlencode($tresult[0])."\" title=\"".urlencode($tresult[1])."\" style=\"background: $background;\" >"._("Trunk")." ".substr(str_replace('AMP:', '', $tresult[1]),0,15)."</a></li>\n";
+}
+
+?>
+</ul>
+</div>
+
+<div class="content">
+
+<?php 
+
+if (!$tech && !$extdisplay) {
+?>
+	<h2><?php echo _("Add a Trunk")?></h2>
+	<a href="<?php echo $_SERVER['PHP_SELF'].'?display='.urlencode($display); ?>&amp;tech=ZAP"><?php echo _("Add ZAP Trunk")?></a><br><br>
+	<a href="<?php echo $_SERVER['PHP_SELF'].'?display='.urlencode($display); ?>&amp;tech=IAX2"><?php echo _("Add IAX2 Trunk")?></a><br><br>
+	<a href="<?php echo $_SERVER['PHP_SELF'].'?display='.urlencode($display); ?>&amp;tech=SIP"><?php echo _("Add SIP Trunk")?></a><br><br>
+	<a href="<?php echo $_SERVER['PHP_SELF'].'?display='.urlencode($display); ?>&amp;tech=ENUM"><?php echo _("Add ENUM Trunk")?></a><br><br>
+	<a href="<?php echo $_SERVER['PHP_SELF'].'?display='.urlencode($display); ?>&amp;tech=CUSTOM"><?php echo _("Add Custom Trunk")?></a><br><br>
+<?php 
+} else {
+	if ($extdisplay) {
+		//list($trunk_tech, $trunk_name) = explode("/",$tname);
+		//if ($trunk_tech == "IAX2") $trunk_tech = "IAX"; // same thing
+		$tech = core_trunks_getTrunkTech($trunknum);
+
+		$outcid = ${"OUTCID_".$trunknum};
+		$maxchans = ${"OUTMAXCHANS_".$trunknum};
+		$dialoutprefix = ${"OUTPREFIX_".$trunknum};
+		$keepcid = isset(${"OUTKEEPCID_".$trunknum})?${"OUTKEEPCID_".$trunknum}:'';
+		$failtrunk = isset(${"OUTFAIL_".$trunknum})?${"OUTFAIL_".$trunknum}:'';
+		$failtrunk_enable = ($failtrunk == "")?'':'CHECKED';
+		$disabletrunk = isset(${"OUTDISABLE_".$trunknum})?${"OUTDISABLE_".$trunknum}:'';
+		
+		if ($tech!="enum") {
+	
+			if (!isset($channelid)) {
+				$channelid = core_trunks_getTrunkTrunkName($trunknum); 
+			}
+
+			if ($tech!="custom") {  // custom trunks will not have user/peer details in database table
+				// load from db
+				if (!isset($peerdetails)) {	
+					$peerdetails = core_trunks_getTrunkPeerDetails($trunknum);
+				}
+	
+				if (!isset($usercontext)) {	
+					$usercontext = core_trunks_getTrunkUserContext($trunknum); 
+				}
+	
+				if (!isset($userconfig)) {	
+					$userconfig = core_trunks_getTrunkUserConfig($trunknum);
+				}
+					
+				if (!isset($register)) {	
+					$register = core_trunks_getTrunkRegister($trunknum);
+				}
+			}
+		}
+		
+		if (count($dialrules) == 0) {
+			if ($temp = core_trunks_getDialRules($trunknum)) {
+				foreach ($temp as $key=>$val) {
+					// extract all ruleXX keys
+					if (preg_match("/^rule\d+$/",$key)) {
+						$dialrules[] = $val;
+					}
+				}
+			}
+			unset($temp);
+		}
+		
+		echo "<h2>".sprintf(_("Edit %s Trunk"),strtoupper($tech))."</h2>";
+?>
+		<p><a title="<?php echo $channelid ?>" href="config.php?display=<?php echo urlencode($display) ?>&amp;extdisplay=<?php echo urlencode($extdisplay) ?>&amp;action=deltrunk"><?php echo _("Delete Trunk")?> <?php  echo substr($channelid,0,20); ?></a></p>
+<?php 
+
+		// find which routes use this trunk
+		$routes = core_trunks_gettrunkroutes($trunknum);
+		$num_routes = count($routes);
+		if ($num_routes > 0) {
+			echo "<a href=# class=\"info\">"._("In use by")." ".$num_routes." ".($num_routes == 1 ? _("route") : _("routes"))."<span>";
+			foreach($routes as $route=>$priority) {
+				echo _("Route")." <b>".$route."</b>: "._("Sequence")." <b>".$priority."</b><br>";
+			}
+			echo "</span></a>";
+		} else {
+			echo "<b>"._("WARNING:")."</b> <a href=# class=\"info\">"._("This trunk is not used by any routes!")."<span>";
+			echo _("This trunk will not be able to be used for outbound calls until a route is setup that uses it. Click on <b>Outbound Routes</b> to setup routing.");
+			echo "</span></a>";
+		}
+		echo "<br><br>";
+
+	} else {
+		// set defaults
+		$outcid = "";
+		$maxchans = "";
+		$dialoutprefix = "";
+		
+		if ($tech == "zap") {
+			$channelid = "g0";
+		} else {
+			$channelid = "";
+		}
+		
+		// only for iax2/sip
+		$peerdetails = "host=***provider ip address***\nusername=***userid***\nsecret=***password***\ntype=peer";
+		$usercontext = "";
+		$userconfig = "secret=***password***\ntype=user\ncontext=from-trunk";
+		$register = "";
+		
+		$localpattern = "NXXXXXX";
+		$lddialprefix = "1";
+		$areacode = "";
+	
+		echo "<h2>".sprintf("Add %s Trunk",strtoupper($tech))."</h2>";
+	} 
+?>
+	
+		<form name="trunkEdit" action="config.php" method="post" onsubmit="return trunkEdit_onsubmit('<?php echo ($extdisplay ? "edittrunk" : "addtrunk") ?>');">
+			<input type="hidden" name="display" value="<?php echo $display?>"/>
+			<input type="hidden" name="extdisplay" value="<?php echo $extdisplay ?>"/>
+			<input type="hidden" name="action" value=""/>
+			<input type="hidden" name="tech" value="<?php echo $tech?>"/>
+			<table>
+			<tr>
+				<td colspan="2">
+					<h4><?php echo _("General Settings")?></h4>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<a href=# class="info"><?php echo _("Outbound Caller ID")?><span><br><?php echo _("Caller ID for calls placed out on this trunk<br><br>Format: <b>\"caller name\" &lt;#######&gt;</b>. You can also use the magic string 'hidden' to hide the CallerID sent out over Digital lines ONLY (E1/T1/J1/BRI/SIP/IAX)")?><br><br></span></a>: 
+				</td><td>
+					<input type="text" size="20" name="outcid" value="<?php echo $outcid;?>"/>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<a href="#" class="info"><?php echo _("Never Override CallerID")?><span><br><?php echo _("Some VoIP providers will drop the call if you try to send an invalid CallerID (one you don't 'own.' Use this to never send a CallerID that you haven't explicitly specified in this trunk or in the outbound callerid field of an extension/user. You might notice this problem if you discover that Follow-Me or RingGroups with external numbers don't work properly. Checking this box has the effect of disabling 'foreign' callerids from going out this trunk. You must define an Outbound Caller ID on the this trunk when checking this.");?><br /><br /></span></a>:
+				</td><td>
+					<input type="checkbox" name="keepcid" <?php if ($keepcid=="on") {echo "checked";}?>/>
+				</td>
+			<tr>
+				<td>
+<?php
+	if ($tech == "sip" || substr($tech,0,3) == "iax") {
+?>
+					<a href=# class="info"><?php echo _("Maximum channels")?><span><?php echo sprintf(_("Controls the maximum number of outbound channels (simultaneous calls) that can be used on this trunk. To count inbound calls against this maximum, use the auto-generated context: %s as the inbound trunk's context. (see extensions_additional.conf) Leave blank to specify no maximum."),((isset($channelid) && trim($channelid)!="")?"from-trunk-$channelid":"from-trunk-[trunkname]"))?></span></a>: 
+<?php
+	} else {
+?>
+					<a href=# class="info"><?php echo _("Maximum channels")?><span><?php echo _("Controls the maximum number of outbound channels (simultaneous calls) that can be used on this trunk. Inbound calls are not counted against the maximum. Leave blank to specify no maximum.")?></span></a>: 
+<?php
+	}
+?>
+				</td><td>
+					<input type="text" size="3" name="maxchans" value="<?php echo htmlspecialchars($maxchans); ?>"/>
+				</td>
+			</tr>
+
+			<tr>
+			    <td><a class="info" href="#"><?php echo _("Disable Trunk")?><span><?php echo _("Check this to disable this trunk in all routes where it is used.")?></span></a>:
+			    </td>
+			    <td>
+				<input type='checkbox' name='disabletrunk' id="disabletrunk" <?php if ($disabletrunk=="on") { echo 'CHECKED'; }?> OnClick='disable_verify(disabletrunk); return true;'><small><?php echo _("Disable")?></small>
+			    </td>
+			</tr>
+
+			<tr>
+			    <td><a class="info" href="#"><?php echo _("Monitor Trunk Failures")?><span><?php echo _("If checked, supply the name of a custom AGI Script that will be called to report, log, email or otherwise take some action on trunk failures that are not caused by either NOANSWER or CANCEL.")?></span></a>:
+			    </td>
+			    <td>
+				<input <?php if (!$failtrunk_enable) echo "disabled style='background: #DDD;'"?> type="text" size="20" name="failtrunk" value="<?php echo htmlspecialchars($failtrunk)?>"/>
+				<input type='checkbox' name='failtrunk_enable' id="failtrunk_enable" value='1' <?php if ($failtrunk_enable) { echo 'CHECKED'; }?> OnClick='disable_field(failtrunk,failtrunk_enable); return true;'><small><?php echo _("Enable")?></small>
+			    </td>
+			</tr>
+
+			<tr>
+				<td colspan="2">
+					<br><h4><?php echo _("Outgoing Dial Rules")?></h4>
+				</td>
+			</tr>
+			<tr>
+				<td valign="top">
+					<a href=# class="info"><?php echo _("Dial Rules")?><span><?php echo _("A Dial Rule controls how calls will be dialed on this trunk. It can be used to add or remove prefixes. Numbers that don't match any patterns defined here will be dialed as-is. Note that a pattern without a + or | (to add or remove a prefix) will not make any changes but will create a match. Only the first matched rule will be executed and the remaining rules will not be acted on.")?><br /><br /><b><?php echo _("Rules:")?></b><br />
+	<strong>X</strong>&nbsp;&nbsp;&nbsp; <?php echo _("matches any digit from 0-9")?><br />
+	<strong>Z</strong>&nbsp;&nbsp;&nbsp; <?php echo _("matches any digit from 1-9")?><br />
+	<strong>N</strong>&nbsp;&nbsp;&nbsp; <?php echo _("matches any digit from 2-9")?><br />
+	<strong>[1237-9]</strong>&nbsp;   <?php echo _("matches any digit or letter in the brackets (in this example, 1,2,3,7,8,9)")?><br />
+	<strong>.</strong>&nbsp;&nbsp;&nbsp; <?php echo _("wildcard, matches one or more characters (not allowed before a | or +)")?><br />
+	<strong>|</strong>&nbsp;&nbsp;&nbsp; <?php echo _("removes a dialing prefix from the number (for example, 613|NXXXXXX would match when some dialed \"6135551234\" but would only pass \"5551234\" to the trunk)")?>
+	<strong>+</strong>&nbsp;&nbsp;&nbsp; <?php echo _("adds a dialing prefix from the number (for example, 1613+NXXXXXX would match when some dialed \"5551234\" and would pass \"16135551234\" to the trunk)")?><br /><br />
+	<?php echo _("You can also use both + and |, for example: 01+0|1ZXXXXXXXXX would match \"016065551234\" and dial it as \"0116065551234\" Note that the order does not matter, eg. 0|01+1ZXXXXXXXXX does the same thing."); ?>
+					</span></a>:
+				</td><td valign="top">&nbsp;
+					<textarea id="dialrules" cols="20" rows="<?php  
+						if (is_array($dialrules)) {
+							$rows = count($dialrules)+1; 
+							echo (($rows < 5) ? 5 : (($rows > 20) ? 20 : $rows) );
+						} else {
+							echo "5";
+						} ?>" name="dialrules"><?php if(is_array($dialrules)) { echo implode("\n",$dialrules); } ?></textarea><br>
+					
+					<input type="submit" style="font-size:10px;" value="<?php echo _("Clean & Remove duplicates")?>" />
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<a href=# class="info"><?php echo _("Dial rules wizards")?><span>
+					<strong><?php echo _("Always dial with prefix")?></strong> <?php echo _("is useful for VoIP trunks, where if a number is dialed as \"5551234\", it can be converted to \"16135551234\".")?><br>
+					<strong><?php echo _("Remove prefix from local numbers")?></strong> <?php echo _("is useful for ZAP trunks, where if a local number is dialed as \"6135551234\", it can be converted to \"555-1234\".")?><br>
+					<strong><?php echo _("Lookup numbers for local trunk")?></strong> <?php echo _("This looks up your local number on www.localcallingguide.com (NA-only), and sets up so you can dial either 7 or 10 digits (regardless of what your PSTN is) on a local trunk (where you have to dial 1+areacode for long distance, but only 5551234 (7-digit dialing) or 6135551234 (10-digit dialing) for local calls")?><br>
+					</span></a>:
+				</td><td valign="top">&nbsp;&nbsp;<select id="autopop" name="autopop" onChange="changeAutoPop(); ">
+						<option value="" SELECTED><?php echo _("(pick one)")?></option>
+						<option value="always"><?php echo _("Always dial with prefix")?></option>
+						<option value="remove"><?php echo _("Remove prefix from local numbers")?></option>
+						<option value="lookup7"><?php echo _("Lookup numbers for local trunk (7-digit dialing)")?></option>
+						<option value="lookup10"><?php echo _("Lookup numbers for local trunk (10-digit dialing)")?></option>
+					</select>
+				</td>
+			</tr>
+			<input id="npanxx" name="npanxx" type="hidden" />
+			<script language="javascript">
+			
+			function disable_field(field, field_enable) {
+			    if (field_enable.checked) {
+				field.style.backgroundColor = '#FFF';
+				field.disabled = false;
+			    }
+			    else {
+				field.style.backgroundColor = '#DDD';
+				field.disabled = true;
+			    }
+			}
+
+			function disable_verify(field) {
+			    if (field.checked) {
+				var answer=confirm("Are you sure you want to disable this trunk in all routes it is used?");
+				if (!answer) {
+				    field.checked = false;
+				}
+			    }
+			    else {
+				alert("You have enabled this trunk in all routes it is used");
+			    }
+			}
+
+			function populateLookup(digits) {
+<?php 
+	if (function_exists("curl_init")) { // curl is installed
+?>				
+				//var npanxx = prompt("What is your areacode + prefix (NPA-NXX)?", document.getElementById('areacode').value);
+				do {
+					var npanxx = <?php echo 'prompt("'._("What is your areacode + prefix (NPA-NXX)?\\n\\n(Note: this database contains North American numbers only, and is not guaranteed to be 100% accurate. You will still have the option of modifying results.)\\n\\nThis may take a few seconds.".'")')?>;
+					if (npanxx == null) return;
+				} while (!npanxx.match("^[2-9][0-9][0-9][-]?[2-9][0-9][0-9]$") && <?php echo '!alert("'._("Invalid NPA-NXX. Must be of the format \'NXX-NXX\'").'")'?>);
+				
+				document.getElementById('npanxx').value = npanxx;
+				if (digits == 10) {
+					document.trunkEdit.action.value = "populatenpanxx10";
+				} else {
+					document.trunkEdit.action.value = "populatenpanxx7";
+				}
+				document.trunkEdit.submit();
+<?php  
+	} else { // curl is not installed
+?>
+				<?php echo 'alert("'._("Error: Cannot continue!\\n\\nPrefix lookup requires cURL support in PHP on the server. Please install or enable cURL support in your PHP installation to use this function. See http://www.php.net/curl for more information.").'")'?>;
+<?php 
+	}
+?>
+			}
+			
+			function populateAlwaysAdd() {
+				do {
+					var localpattern = <?php echo 'prompt("'._("What is the local dialing pattern?\\n\\n(ie. NXXNXXXXXX for US/CAN 10-digit dialing, NXXXXXX for 7-digit)").'"'?>,"NXXXXXX");
+					if (localpattern == null) return;
+				} while (!localpattern.match('^[0-9#*ZXN\.]+$') && <?php echo '!alert("'._("Invalid pattern. Only 0-9, #, *, Z, N, X and . are allowed.").'")'?>);
+				
+				do {
+					var localprefix = <?php echo 'prompt("'._("What prefix should be added to the dialing pattern?\\n\\n(ie. for US/CAN, 1+areacode, ie, \'1613\')?").'")'?>;
+					if (localprefix == null) return;
+				} while (!localprefix.match('^[0-9#*]+$') && <?php echo '!alert("'._("Invalid prefix. Only dialable characters (0-9, #, and *) are allowed.").'")'?>);
+
+				dialrules = document.getElementById('dialrules');
+				if (dialrules.value[dialrules.value.length-1] != '\n') {
+					dialrules.value = dialrules.value + '\n';
+				}
+				dialrules.value = dialrules.value + localprefix + '+' + localpattern + '\n';
+			}
+			
+			function populateRemove() {
+				do {
+					var localprefix = <?php echo 'prompt("'._("What prefix should be removed from the number?\\n\\n(ie. for US/CAN, 1+areacode, ie, \'1613\')").'")'?>;
+					if (localprefix == null) return;
+				} while (!localprefix.match('^[0-9#*ZXN\.]+$') && <?php echo '!alert("'._('Invalid prefix. Only 0-9, #, *, Z, N, and X are allowed.').'")'?>);
+				
+				do {
+					var localpattern = <?php echo 'prompt("'._("What is the dialing pattern for local numbers after")?> "+localprefix+"? \n\n<?php echo _("(ie. NXXNXXXXXX for US/CAN 10-digit dialing, NXXXXXX for 7-digit)").'"'?>,"NXXXXXX");
+					if (localpattern == null) return;
+				} while (!localpattern.match('^[0-9#*ZXN\.]+$') && <?php echo '!alert("'._("Invalid pattern. Only 0-9, #, *, Z, N, X and . are allowed.").'")'?>);
+				
+				dialrules = document.getElementById('dialrules');
+				if (dialrules.value[dialrules.value.length-1] != '\n') {
+					dialrules.value = dialrules.value + '\n';
+				}
+				dialrules.value = dialrules.value + localprefix + '|' + localpattern + '\n';
+			}
+			
+			function changeAutoPop() {
+				switch(document.getElementById('autopop').value) {
+					case "always":
+						populateAlwaysAdd();
+					break;
+					case "remove":
+						populateRemove();
+					break;
+					case "lookup7":
+						populateLookup(7);
+					break;
+					case "lookup10":
+						populateLookup(10);
+					break;
+				}
+				document.getElementById('autopop').value = '';
+			}
+			</script>
+<?php /* //DIALRULES
+			<tr>
+				<td>
+					<a href=# class="info">Dial rules<span>The area code this trunk is in.</span></a>: 
+				</td><td>&nbsp;
+					<select id="dialrulestype" name="dialrulestype" onChange="changeRulesType();">
+<?php 
+					$rules = array( "asis" => "Don't change number",
+							"always" => "Always dial prefix+areacode",
+							"local" => "Local 7-digit dialing",
+							"local10" => "Local 10-digit dialing");
+
+					foreach ($rules as $value=>$display) {
+						echo "<option value=\"".$value."\" ".(($value == $dialrulestype) ? "SELECTED" : "").">".$display."</option>";
+					}
+?>
+					</select>
+					
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<a href=# class="info"><?php echo _("Local dialing pattern<span>The dialing pattern to make a 'local' call.</span>")</a>: 
+				</td><td>
+					<input id="localpattern" type="text" size="10" maxlength="20" name="localpattern" value="<?php echo $localpattern ?>"/>
+					
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<a href=# class="info"><?php echo _("Long-distance dial prefix<span>The prefix for dialing long-distance numbers. In north america, this should be \"1\".</span>")?></a>: 
+				</td><td>
+					<input id="lddialprefix" type="text" size="3" maxlength="6" name="lddialprefix" value="<?php echo $lddialprefix ?>"/>
+					
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<a href=# class="info"><?php echo _("Local LD prefix<span>The area code this trunk is in. Any 7-digit numbers that don't match a number in the below list will have dialprefix+areacode added to them. </span>")?></a>: 
+				</td><td>
+					<input id="areacode" type="text" size="3" maxlength="6" name="areacode" value="<?php echo $areacode ?>"/>
+					
+				</td>
+			</tr>
+			<tr>
+				<td valign="top">
+					<a href=# class="info"><?php echo _("Local prefixes<span>This should be a list of local areacodes + prefixes to use for local dialing.</span>")?></a>: 
+				</td><td valign="top">&nbsp;
+					<textarea id="localprefixes" cols="8" rows="<?php  $rows = count($localprefixes)+1; echo (($rows < 5) ? 5 : (($rows > 20) ? 20 : $rows) ); ?>" name="localprefixes"><?php echo  implode("\n",$localprefixes);?></textarea><br>
+					 
+					<input id="npanxx" name="npanxx" type="hidden" /><br>
+					<a href=# class="info"><?php echo _("Populate with local rules<span>Do a lookup from http://members.dandy.net/~czg/search.html to find all local-reachable area codes and phone numbers.</span>")?></a>: <input type="button" value="Go" onClick="checkPopulate();" />
+					<br><br>
+				</td>
+			</tr>
+			<script language="javascript">
+			
+			function checkPopulate() {
+				//var npanxx = prompt("What is your areacode + prefix (NPA-NXX)?", document.getElementById('areacode').value);
+				var npanxx = <?php echo 'prompt("'._("What is your areacode + prefix (NPA-NXX)?").'")'?>;
+				
+				if (npanxx.match("^[2-9][0-9][0-9][-]?[2-9][0-9][0-9]$")) {
+					document.getElementById('npanxx').value = npanxx;
+					trunkEdit.action.value = "populatenpanxx";
+					trunkEdit.submit();
+				} else if (npanxx != null) {
+					<?php echo 'alert("'._("Invalid format for NPA-NXX code (must be format: NXXNXX)").'")'?>;
+				}
+			}
+			
+			function changeRulesType() {
+				switch(document.getElementById('dialrulestype').value) {
+					case "always":
+						document.getElementById('lddialprefix').disabled = false;
+						document.getElementById('areacode').disabled = false;
+						document.getElementById('localprefixes').disabled = true;
+					break;
+					case "local":
+					case "local10":
+						document.getElementById('lddialprefix').disabled = false;
+						document.getElementById('areacode').disabled = false;
+						document.getElementById('localprefixes').disabled = false;
+					break;
+					case "asis":
+					default:
+						document.getElementById('lddialprefix').disabled = true;
+						document.getElementById('areacode').disabled = true;
+						document.getElementById('localprefixes').disabled = true;
+					break;
+				}
+			}
+			changeRulesType();
+			</script>
+*/?>
+			<tr>
+				<td>
+					<a href=# class="info"><?php echo _("Outbound Dial Prefix")?><span><?php echo _("The outbound dialing prefix is used to prefix a dialing string to all outbound calls placed on this trunk. For example, if this trunk is behind another PBX or is a Centrex line, then you would put 9 here to access an outbound line. Another common use is to prefix calls with 'w' on a POTS line that need time to obtain dialtone to avoid eating digits.<br><br>Most users should leave this option blank.")?></span></a>: 
+				</td><td>
+					<input type="text" size="8" name="dialoutprefix" value="<?php echo htmlspecialchars($dialoutprefix) ?>"/>
+				</td>
+			</tr>
+			<?php if ($tech != "enum") { ?>
+			<tr>
+				<td colspan="2">
+					<br><h4><?php echo _("Outgoing Settings")?></h4>
+				</td>
+			</tr>
+			<?php } ?>
+
+	<?php 
+	switch ($tech) {
+		case "zap":
+	?>
+				<tr>
+					<td>
+						<a href=# class="info"><?php echo _("Zap Identifier (trunk name)")?><span><br><?php echo _("ZAP channels are referenced either by a group number or channel number (which is defined in zapata.conf).  <br><br>The default setting is <b>g0</b> (group zero).")?><br><br></span></a>: 
+					</td><td>
+						<input type="text" size="8" name="channelid" value="<?php echo htmlspecialchars($channelid) ?>"/>
+						<input type="hidden" size="14" name="usercontext" value="notneeded"/>
+					</td>
+				</tr>
+	<?php 
+		break;
+		case "enum":
+		break;
+		case "custom":
+	?>
+				<tr>
+					<td>
+						<a href=# class="info"><?php echo _("Custom Dial String")?><span><?php echo _("Define the custom Dial String.  Include the token")?> $OUTNUM$ <?php echo _("wherever the number to dial should go.<br><br><b>examples:</b><br><br>CAPI/XXXXXXXX/")?>$OUTNUM$<?php echo _("/b<br>H323/")?>$OUTNUM$@XX.XX.XX.XX<br>OH323/$OUTNUM$@XX.XX.XX.XX:XXXX<br>vpb/1-1/$OUTNUM$</span></a>: 
+					</td><td>
+						<input type="text" size="35" maxlength="46" name="channelid" value="<?php echo htmlspecialchars($channelid) ?>"/>
+						<input type="hidden" size="14" name="usercontext" value="notneeded"/>
+					</td>
+				</tr>	
+	<?php
+		break;
+		default:
+	?>
+				<tr>
+					<td>
+						<a href=# class="info"><?php echo _("Trunk Name")?><span><br><?php echo _("Give this trunk a unique name.  Example: myiaxtel")?><br><br></span></a>: 
+					</td><td>
+						<input type="text" size="14" name="channelid" value="<?php echo htmlspecialchars($channelid) ?>"/>
+					</td>
+				</tr>
+				<tr>
+					<td colspan="2">
+						<a href=# class="info"><?php echo _("PEER Details")?><span><br><?php echo _("Modify the default PEER connection parameters for your VoIP provider.<br><br>You may need to add to the default lines listed below, depending on your provider.")?><br><br></span></a>: 
+					</td>
+				</tr>
+				<tr>
+					<td colspan="2">
+						<textarea rows="10" cols="40" name="peerdetails"><?php echo htmlspecialchars($peerdetails) ?></textarea>
+					</td>
+				</tr>
+				<tr>
+					<td colspan="2">
+						<br><h4><?php echo _("Incoming Settings")?></h4>
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<a href=# class="info"><?php echo _("USER Context")?><span><br><?php echo _("This is most often the account name or number your provider expects.<br><br>This USER Context will be used to define the below user details.")?></span></a>: 
+					</td><td>
+						<input type="text" size="14" name="usercontext" value="<?php echo htmlspecialchars($usercontext)  ?>"/>
+					</td>
+				</tr>
+				<tr>
+					<td colspan="2">
+						<a href=# class="info"><?php echo _("USER Details")?><span><br><?php echo _("Modify the default USER connection parameters for your VoIP provider.")?><br><br><?php echo _("You may need to add to the default lines listed below, depending on your provider.")?><br><br></span></a>: 
+					</td>
+				</tr>
+				<tr>
+					<td colspan="2">
+						<textarea rows="10" cols="40" name="userconfig"><?php echo htmlspecialchars($userconfig); ?></textarea>
+					</td>
+				</tr>
+				<tr>
+					<td colspan="2">
+						<br><h4><?php echo _("Registration")?></h4>
+					</td>
+				</tr>
+				<tr>
+					<td colspan="2">
+						<a href=# class="info"><?php echo _("Register String")?><span><br><?php echo _("Most VoIP providers require your system to REGISTER with theirs. Enter the registration line here.<br><br>example:<br><br>username:password at switch.voipprovider.com.<br><br>Many providers will require you to provide a DID number, ex: username:password at switch.voipprovider.com/didnumber in order for any DID matching to work.")?><br><br></span></a>: 
+					</td>
+				</tr>
+				<tr>
+					<td colspan="2">
+						<input type="text" size="40" name="register" value="<?php echo htmlspecialchars($register) ?>"/>
+					</td>
+				</tr>
+	<?php 
+		break;
+	}
+	?>
+				
+			<tr>
+				<td colspan="2">
+					<h6><input name="Submit" type="submit" value="<?php echo _("Submit Changes")?>"></h6>
+				</td>
+			</tr>
+			</table>
+
+<script language="javascript">
+<!--
+
+var theForm = document.trunkEdit;
+
+theForm.outcid.focus();
+
+function trunkEdit_onsubmit(act) {
+	var msgInvalidOutboundCID = "<?php echo _('Invalid Outbound Caller ID'); ?>";
+	var msgInvalidMaxChans = "<?php echo _('Invalid Maximum Channels'); ?>";
+	var msgInvalidDialRules = "<?php echo _('Invalid Dial Rules'); ?>";
+	var msgInvalidOutboundDialPrefix = "<?php echo _('Invalid Outbound Dial Prefix'); ?>";
+	var msgInvalidTrunkName = "<?php echo _('Invalid Trunk Name entered'); ?>";
+	var msgInvalidChannelName = "<?php echo _('Invalid Custom Dial String entered'); ?>"; 
+	var msgInvalidTrunkAndUserSame = "<?php echo _('Trunk Name and User Context cannot be set to the same value'); ?>";
+	var msgConfirmBlankContext = "<?php echo _('User Context was left blank and User Details will not be saved!'); ?>";
+	var msgNeverOverrideCIDValue = "<?php echo _('You must define an Outbound Caller ID when Choosing Never Override CallerID'); ?>";
+
+	defaultEmptyOK = true;
+
+	if (theForm.keepcid.checked && isEmpty($.trim(theForm.outcid.value)))
+		return warnInvalid(theForm.outcid, msgNeverOverrideCIDValue);
+
+	if (!isCallerID(theForm.outcid.value))
+		return warnInvalid(theForm.outcid, msgInvalidOutboundCID);
+	
+	if (!isInteger(theForm.maxchans.value))
+		return warnInvalid(theForm.maxchans, msgInvalidMaxChans);
+	
+	if (!isDialrule(theForm.dialrules.value))
+		return warnInvalid(theForm.dialrules, msgInvalidDialRules);
+	
+	if (!isDialIdentifierSpecial(theForm.dialoutprefix.value))
+		return warnInvalid(theForm.dialoutprefix, msgInvalidOutboundDialPrefix);
+	
+	<?php if ($tech != "enum" && $tech != "custom") { ?>
+	defaultEmptyOK = true;
+	if (isEmpty(theForm.channelid.value) || isWhitespace(theForm.channelid.value))
+		return warnInvalid(theForm.channelid, msgInvalidTrunkName);
+	
+	if (theForm.channelid.value == theForm.usercontext.value)
+		return warnInvalid(theForm.usercontext, msgInvalidTrunkAndUserSame);
+	<?php } else if ($tech == "custom") { ?> 
+	if (isEmpty(theForm.channelid.value) || isWhitespace(theForm.channelid.value)) 
+		return warnInvalid(theForm.channelid, msgInvalidChannelName); 
+
+	if (theForm.channelid.value == theForm.usercontext.value) 
+		return warnInvalid(theForm.usercontext, msgInvalidTrunkAndUserSame);
+	<?php } ?>
+
+	<?php if ($tech == "sip" || substr($tech,0,3) == "iax") { ?>
+	if ((isEmpty(theForm.usercontext.value) || isWhitespace(theForm.usercontext.value)) && 
+		(!isEmpty(theForm.userconfig.value) && !isWhitespace(theForm.userconfig.value)) &&
+			(theForm.userconfig.value != "secret=***password***\ntype=user\ncontext=from-trunk")) {
+				if (confirm(msgConfirmBlankContext) == false)
+				return false;
+			}
+	<?php } ?>
+
+	theForm.action.value = act;
+	return true;
+}
+
+function isDialIdentifierSpecial(s) { // special chars allowed in dial prefix (e.g. fwdOUT)
+    var i;
+
+    if (isEmpty(s)) 
+       if (isDialIdentifierSpecial.arguments.length == 1) return defaultEmptyOK;
+       else return (isDialIdentifierSpecial.arguments[1] == true);
+
+    for (i = 0; i < s.length; i++)
+    {   
+        var c = s.charAt(i);
+
+        if ( !isDialDigitChar(c) && (c != "w") && (c != "W") && (c != "q") && (c != "Q") && (c != "+") ) return false;
+    }
+
+    return true;
+}
+//-->
+</script>
+
+		</form>
+<?php  
+}
+?>
+
+

Added: freepbx-modules/trunk/modules/core/page.users.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/core/page.users.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/core/page.users.php (added)
+++ freepbx-modules/trunk/modules/core/page.users.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,48 @@
+<?php /* $Id: page.users.php 2617 2006-09-26 11:43:51Z qldrob $ */
+//Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+?>
+
+<div class="rnav">
+<?php 
+// Eventually I recon the drawListMenu could be built into the new component class thus making
+// the relevent page.php file unnessassary
+
+$extens = core_users_list();
+drawListMenu($extens, $skip, $type, $display, $extdisplay, _("User"));
+?>
+</div>
+
+<?php
+// Javascript functions could be put into the configpageinit function but I personally prefer
+// to code JavaScript in a web page //
+?>
+
+<script language="javascript">
+<!--
+
+function checkBlankUserPwd() {
+	msgConfirmBlankUserPwd = "<?php echo _('You have not entered a User Password.  While this is acceptable, this user will not be able to login to an AdHoc device.\n\nAre you sure you wish to leave the User Password empty?'); ?>";
+
+	// check for password and warn if none entered
+	if (isEmpty(theForm.password.value)) {
+		var cnf = confirm(msgConfirmBlankUserPwd);
+		if (!cnf) {
+			theForm.password.focus();
+			return false;
+		}
+	}
+	return true;
+}
+
+//-->
+</script>

Modified: freepbx-modules/trunk/modules/customerdb/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/customerdb/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/customerdb/module.xml (original)
+++ freepbx-modules/trunk/modules/customerdb/module.xml Mon Apr  7 13:18:05 2008
@@ -1,17 +1,17 @@
 <module>
 	<rawname>customerdb</rawname>
 	<name>Customer DB</name>
-	<version>1.2.3</version>
+	<version>1.2.3.1</version>
 	<type>tool</type>
 	<category>Third Party Addon</category>
 	<menuitems>
 		<customerdb>Customer DB</customerdb>
 	</menuitems>
 	<changelog>
+		*1.2.3.1* bump for rc1
 		*1.2.3* Add he_IL translation
 	</changelog>
-	<location>release/2.2/customerdb-1.2.2.tgz</location>
-	<md5sum>835304cb4eca3f13423357afdb47c705</md5sum>
-	<info>http://freepbx.org/wiki/CustomerDB</info>
+	<location>release/2.3/customerdb-1.2.3.tgz</location>
+	<md5sum>7993b668880c3f5287fb44b4909546fb</md5sum>
 </module>
 

Added: freepbx-modules/trunk/modules/dashboard/class.astinfo.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/class.astinfo.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/class.astinfo.php (added)
+++ freepbx-modules/trunk/modules/dashboard/class.astinfo.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,235 @@
+<?php
+
+class astinfo {
+	var $astman;
+	
+	function astinfo(&$astman) {
+		$this->astman =& $astman;
+	}
+	
+	function get_channel_totals() {
+		if (!$this->astman) {
+			return array(
+				'external_calls'=>0,
+				'internal_calls'=>0,
+				'total_calls'=>0,
+				'total_channels'=>0,
+			);
+		}
+		$response = $this->astman->send_request('Command',array('Command'=>"show channels"));
+		$astout = explode("\n",$response['data']);
+		
+		$external_calls = 0;
+		$internal_calls = 0;
+		$total_calls = 0;
+		$total_channels = 0;
+		
+		foreach ($astout as $line) {
+			if (preg_match('/s at macro-dialout/', $line)) {
+				$external_calls++;
+			} else if (preg_match('/s at macro-dial:/', $line)) {
+				$internal_calls++;
+			} else if (preg_match('/^(\d+) active channel/i', $line, $matches)) {
+				$total_channels = $matches[1];
+			} else if (preg_match('/^(\d+) active call/i', $line, $matches)) {
+				$total_calls = $matches[1];
+			}
+		}
+		return array(
+			'external_calls'=>$external_calls,
+			'internal_calls'=>$internal_calls,
+			'total_calls'=>$total_calls,
+			'total_channels'=>$total_channels,
+		);
+	}
+	
+	function get_connections($trunks = false) {
+		if (!$trunks) {
+			$trunks = array();
+		}
+		
+		$return = array(
+			'sip_users_online' => 0,
+			'sip_users_offline' => 0,
+			'sip_users_total' => 0,
+			'sip_trunks_online' => 0,
+			'sip_trunks_offline' => 0,
+			'sip_trunks_total' => 0,
+			'sip_registrations_online' => 0,
+			'sip_registrations_offline' => 0,
+			'sip_registrations_total' => 0,
+
+			
+			'iax2_users_online' => 0,
+			'iax2_users_offline' => 0,
+			'iax2_users_total' => 0,
+			'iax2_trunks_online' => 0,
+			'iax2_trunks_offline' => 0,
+			'iax2_trunks_total' => 0,
+			'iax2_registrations_online' => 0,
+			'iax2_registrations_offline' => 0,
+			'iax2_registrations_total' => 0,
+
+			//totals
+			'users_online' => 0,
+			'users_offline' => 0,
+			'users_total' => 0,
+			'trunks_online' => 0,
+			'trunks_offline' => 0,
+			'trunks_total' => 0,
+			'registrations_online' => 0,
+			'registrations_offline' => 0,
+			'registrations_total' => 0,
+		);
+
+		if (!$this->astman) {
+			return $return;
+		}
+
+		$response = $this->astman->send_request('Command',array('Command'=>"sip show peers"));
+		$astout = explode("\n",$response['data']);	
+		foreach ($astout as $line) {
+			if (preg_match('/^(([a-z0-9\-_]+)(\/([a-z0-9\-_]+))?)\s+(\([a-z]+\)|\d{1,3}(\.\d{1,3}){3})/i', $line, $matches)) {
+				//matches: [2] = name, [4] = username, [5] = host, [6] = part of ip (if IP)
+
+				// have an IP address listed, so its online
+				$online = !empty($matches[6]); 
+
+				if (isset($trunks[$matches[2]])) {
+					// this is a trunk
+					//TODO match trunk tech as well? 
+					$return['sip_trunks_'.($online?'online':'offline')]++;
+				} else {
+					$return['sip_users_'.($online?'online':'offline')]++;
+				}
+			}
+		}
+		
+		
+		$response = $this->astman->send_request('Command',array('Command'=>"sip show registry"));
+		$astout = explode("\n",$response['data']);
+		$pos = false;
+		foreach ($astout as $line) {
+			if (trim($line) != '') {
+				if ($pos===false) {
+					// find the position of "State" in the first line
+					$pos = strpos($line,"State");
+				} else {
+					// subsequent lines, check if it syas "Registered" at that position
+					if (substr($line,$pos,10) == "Registered") {
+						$return['sip_registrations_online']++;
+					} else {
+						$return['sip_registrations_offline']++;
+					}
+				}
+			}
+		}
+
+		
+		$response = $this->astman->send_request('Command',array('Command'=>"iax2 show peers"));
+		$astout = explode("\n",$response['data']);
+		foreach ($astout as $line) {
+			if (preg_match('/^(([a-z0-9\-_]+)(\/([a-z0-9\-_]+))?)\s+(\([a-z]+\)|\d{1,3}(\.\d{1,3}){3})/i', $line, $matches)) {
+				//matches: [2] = name, [4] = username, [5] = host, [6] = part of ip (if IP)
+
+				// have an IP address listed, so its online
+				$online = !empty($matches[6]); 
+
+				if (isset($trunks[$matches[2]])) {
+					// this is a trunk
+					//TODO match trunk tech as well? 
+					$return['iax2_trunks_'.($online?'online':'offline')]++;
+				} else {
+					$return['iax2_users_'.($online?'online':'offline')]++;
+				}
+			}
+		}
+		
+		
+		$response = $this->astman->send_request('Command',array('Command'=>"iax2 show registry"));
+		$astout = explode("\n",$response['data']);
+		$pos = false;
+		foreach ($astout as $line) {
+			if (trim($line) != '') {
+				if ($pos===false) {
+					// find the position of "State" in the first line
+					$pos = strpos($line,"State");
+				} else {
+					// subsequent lines, check if it syas "Registered" at that position
+					if (substr($line,$pos,10) == "Registered") {
+						$return['sip_registrations_online']++;
+					} else {
+						$return['sip_registrations_offline']++;
+					}
+				}
+			}
+		}
+
+		
+		$return['sip_users_total'] = $return['sip_users_online'] + $return['sip_users_offline'];
+		$return['sip_trunks_total'] = $return['sip_trunks_online'] + $return['sip_trunks_offline'];
+		$return['sip_registrations_total'] = $return['sip_registrations_online'] + $return['sip_registrations_offline'];
+
+		$return['iax2_users_total'] = $return['iax2_users_online'] + $return['iax2_users_offline'];
+		$return['iax2_trunks_total'] = $return['iax2_trunks_online'] + $return['iax2_trunks_offline'];
+		$return['iax2_registrations_total'] = $return['iax2_registrations_online'] + $return['iax2_registrations_offline'];
+
+		$return['users_online'] = $return['sip_users_online'] + $return['iax2_users_online'];
+		$return['users_offline'] = $return['sip_users_offline'] + $return['iax2_users_offline'];
+		$return['users_total'] = $return['users_online'] + $return['users_offline'];
+		
+		$return['trunks_online'] = $return['sip_trunks_online'] + $return['iax2_trunks_online'];
+		$return['trunks_offline'] = $return['sip_trunks_offline'] + $return['iax2_trunks_offline'];
+		$return['trunks_total'] = $return['trunks_online'] + $return['trunks_offline'];
+
+		$return['registrations_online'] = $return['sip_registrations_online'] + $return['iax2_registrations_online'];
+		$return['registrations_offline'] = $return['sip_registrations_offline'] + $return['iax2_registrations_offline'];
+		$return['registrations_total'] = $return['registrations_online'] + $return['registrations_offline'];
+
+		return $return;
+	}
+	
+	function get_uptime() {
+		/*
+		System uptime: 1 week, 4 days, 22 hours, 29 minutes, 21 seconds
+		Last reload: 1 week, 1 day, 6 hours, 14 minutes, 49 seconds
+		*/
+		$output = array(
+			'system' => '',
+			'reload' => '',
+		);
+
+		if (!$this->astman) {
+			return $output;
+		}
+
+		$response = $this->astman->send_request('Command',array('Command'=>"show uptime"));
+		$astout = explode("\n",$response['data']);
+			
+		foreach ($astout as $line) {
+			if (preg_match('/^System uptime: (.*)$/i',$line,$matches)) {
+				$output["system"] = preg_replace('/,\s+(\d+ seconds?)?\s*$/', '', $matches[1]);				
+			} else if (preg_match('/^Last reload: (.*)$/i',$line,$matches)) {
+				$output["reload"] = preg_replace('/,\s+(\d+ seconds?)?\s*$/', '', $matches[1]);
+			}
+		}
+		
+		return $output;
+	}
+	
+	function check_asterisk() {
+		if (!$this->astman) {
+			return false;
+		}
+		$response = $this->astman->send_request('Command',array('Command'=>"show version"));
+		$astout = explode("\n",$response['data']);
+		
+		if (!preg_match('/^Asterisk /i', $astout[1])) {
+			return false;
+		} else {
+			return $astout[1];
+		}
+	}
+}
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/class.average_rate_calculator.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/class.average_rate_calculator.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/class.average_rate_calculator.php (added)
+++ freepbx-modules/trunk/modules/dashboard/class.average_rate_calculator.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,67 @@
+<?php
+
+/** Takes a list of numbers, and calculates the average rate (delta) of change
+ * Greg MacLellan, July 9, 2007
+ */
+class average_rate_calculator {
+	var $_max_age;
+	var $_values;
+	
+	/** Constructor 
+	 * @param   array	A reference to an array to use for storage. This will be populated with key/value pairs that store the time/value, respectively.
+	 * 			Because it is passed by reference, it can be stored externally in a session or database, allowing persistant use of this object
+	 *			across page loads.
+	 * @param  int	The maximum age of values to store, in seconds
+	 */
+	function average_rate_calculator(&$storage_array, $max_age) {
+		$this->_max_age = $max_age;
+		if (!is_array($storage_array)) {
+			$storage_array = array();
+		}
+		$this->_values =& $storage_array;
+	}
+	/** Adds a value to the array
+	 * @param  float	The value to add
+	 * @param  int	The timestamp to use for this value, defaults to now
+	 */
+	function add($value, $timestamp=null) {
+		if (!$timestamp) $timestamp = time();
+		$this->_values[$timestamp] = $value;
+	}
+	/** Calculate the average per second value 
+	 * @return  The average value, as a rate per second
+	 */
+	function average() {
+		$this->_clean();
+		
+		$avgs = array();
+		$last_time = false;
+		$last_val = false;
+		foreach ($this->_values as $time=>$val) {
+			if ($last_time) {
+				$avgs[] = ($val - $last_val) / ($time - $last_time);
+			}
+			$last_time = $time;
+			$last_val = $val;
+		}
+		// return the average of all our averages
+		if ($count = count($avgs)) {
+			return array_sum($avgs) / $count;
+		} else {
+			return 'unknown';
+		}
+	}
+	/** Clean old values out of the array
+	 */
+	function _clean() {
+		$too_old = time() - $this->_max_age;
+		
+		foreach (array_keys($this->_values) as $key) {
+			if ($key < $too_old) {
+				unset($this->_values[$key]);
+			}
+		}
+	}
+}
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/class.error.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/class.error.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/class.error.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/class.error.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,141 @@
+<?php 
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+// 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.
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// $Id: class.error.inc.php,v 1.4 2006/02/27 21:01:44 bigmichi1 Exp $
+
+class Error {
+
+	// Array which holds the error messages
+	var $arrErrorList 	= array();
+	// current number of errors encountered
+	var $errors 		= 0;
+
+	/**
+	*
+	*  addError()
+	*  
+	*  @param	strCommand	string		Command, which cause the Error
+	*  @param	strMessage	string		additional Message, to describe the Error
+	*  @param	intLine		integer		on which line the Error occours
+	*  @param	strFile		string		in which File the Error occours
+	*
+	*  @return	-
+	*
+	**/
+	function addError( $strCommand, $strMessage, $intLine, $strFile ) {
+		$this->arrErrorList[$this->errors]['command'] = $strCommand;
+		$this->arrErrorList[$this->errors]['message'] = $strMessage;
+		$this->arrErrorList[$this->errors]['line']    = $intLine;
+		$this->arrErrorList[$this->errors]['file']    = basename( $strFile );
+		$this->errors++;
+	}
+
+	/**
+	*
+	* ErrorsAsHTML()
+	*
+	* @param	-
+	*
+	* @return	string		string which contains a HTML table which can be used to echo out the errors
+	*
+	**/
+	function ErrorsAsHTML() {
+		$strHTMLString = "";
+		$strWARNString = "";
+		$strHTMLhead = "<table width=\"100%\" border=\"0\">\n"
+		 . " <tr>\n"
+		 . "  <td><font size=\"-1\"><b>File</b></font></td>\n"
+		 . "  <td><font size=\"-1\"><b>Line</b></font></td>\n"
+		 . "  <td><font size=\"-1\"><b>Command</b></font></td>\n"
+		 . "  <td><font size=\"-1\"><b>Message</b></font></td>\n"
+		 . " </tr>\n";
+		$strHTMLfoot = "</table>";
+
+		if( $this->errors > 0 ) {
+			foreach( $this->arrErrorList as $arrLine ) {
+				if( $arrLine['command'] == "WARN" ) {
+					$strWARNString .= "<font size=\"-1\"><b>WARNING: " . htmlspecialchars( $arrLine['message'] ) . "</b></font><br/>\n";
+				} else {
+					$strHTMLString .= " <tr>\n"
+                          . "  <td><font size=\"-1\">" . htmlspecialchars( $arrLine['file'] ) . "</font></td>\n"
+					                . "  <td><font size=\"-1\">" . $arrLine['line'] . "</font></td>\n"
+					                . "  <td><font size=\"-1\">" . htmlspecialchars( $arrLine['command'] ) . "</font></td>\n"
+					                . "  <td><font size=\"-1\">" . htmlspecialchars( $arrLine['message'] ) . "</font></td>\n"
+					                . " </tr>\n";
+				}
+			}
+		}
+    
+		if( !empty( $strHTMLString ) ) {
+			$strHTMLString = $strWARNString . $strHTMLhead . $strHTMLString . $strHTMLfoot;
+		} else {
+			$strHTMLString = $strWARNString;
+		}
+
+		return $strHTMLString;
+	}
+
+	/**
+	*
+	* ErrorsAsText()
+	*
+	* @param	-
+	*
+	* @return	string		string which contains a table which can be used to echo out the errors
+	*
+	**/
+	function ErrorsAsText() {
+		$strHTMLString = "";
+		$strWARNString = "";
+		$strHTMLhead = sprintf("%24s %6s %40s %s\n","File", "Line", "Command", "Message");
+		$strHTMLfoot = "\n";
+
+		if( $this->errors > 0 ) {
+ 			foreach( $this->arrErrorList as $arrLine ) {
+				if( $arrLine['command'] == "WARN" ) {
+					$strWARNString .= "WARNING: " . $arrLine['message'] . "\n";
+				} else {
+					$strHTMLString .= sprintf("%24s %6s %40s %s\n",$arrLine['file'], $arrLine['line'], $arrLine['command'], $arrLine['message'] );
+				}
+			}
+		}
+    
+    if( !empty( $strHTMLString ) ) {
+      $strHTMLString = $strWARNString . $strHTMLhead . $strHTMLString . $strHTMLfoot;
+    } else {
+      $strHTMLString = $strWARNString;
+    }
+    
+    return $strHTMLString;
+  }
+
+	/**
+	*
+	* ErrorsExist()
+	*
+	* @param	-
+	*
+	* @return 	true	there are errors logged
+	*		false	no errors logged
+	*
+	**/
+	function ErrorsExist() {
+		if( $this->errors > 0 ) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+}
+?>

Added: freepbx-modules/trunk/modules/dashboard/class.procinfo.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/class.procinfo.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/class.procinfo.php (added)
+++ freepbx-modules/trunk/modules/dashboard/class.procinfo.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,37 @@
+<?php
+
+class procinfo {
+	var $distro;
+	
+	function procinfo($distro = false) {
+		$this->distro = $distro;
+	}
+	
+	function check_port($port, $server = "localhost") {
+		$timeout = 5;
+		if ($sock = @fsockopen($server, $port, $errno, $errstr, $timeout)) {
+			fclose($sock);
+			return true;
+		}
+		return false;
+	}
+	
+	function check_fop_server() {
+		return $this->check_port(4445);
+	}
+	
+	function check_mysql($hoststr) {
+		$host = 'localhost';
+		$port = '3306';
+		if (preg_match('/^([^:]+)(:(\d+))?$/',$hoststr,$matches)) {
+			// matches[1] = host, [3] = port
+			$host = $matches[1];
+			if (!empty($matches[3])) {
+				$port = $matches[3];
+			}
+		}
+		return $this->check_port($port, $host);
+	}
+}
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/dashboard.css
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/dashboard.css?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/dashboard.css (added)
+++ freepbx-modules/trunk/modules/dashboard/dashboard.css Mon Apr  7 13:18:05 2008
@@ -1,0 +1,147 @@
+#dashboard {
+	position:relative;
+}
+
+/* two columns, sizes of each category box */
+#sysinfo-left, #sysinfo-left .infobox {
+	width:400px;
+}
+#sysinfo-right {
+	position:absolute;
+	width:200px;
+	top:0;
+	margin-left:420px;
+}
+#sysinfo-right .infobox {
+	width:200px;
+}
+
+/* main container for each category of items */
+.infobox {
+	border:1px solid black;
+	padding:0 5px 5px 5px;
+	margin-bottom:1em;
+	background:white;
+	background-image:url(images/dashboard-sysinfo.png);
+	background-repeat:repeat-x;
+	color: #333;
+}
+
+/* headings */
+.infobox h4 , .infobox h3 {
+	margin-bottom:8px;
+	margin-top:5px;
+}
+.infobox h3 {
+	color: white;
+	margin-bottom:2;
+	margin-top:3px;
+}
+
+/* main container for each item */
+.databox {
+	position:relative;
+	border:1px solid #ccc;
+	font-size:9pt;
+	margin-top:4px;
+}
+/* height of main container and actual bar graph */
+.databox , .graphbox .bargraph {
+	height:12pt;
+}
+/* positioning of data title  */
+.databox .dataname {
+	position:absolute;
+	top:1pt;
+	left:2px;
+}
+/* positioning of the value shown in boxes */
+.databox .datavalue {
+	position:absolute;
+	top:1pt;
+	right:2px;
+}
+
+/* graph colors */
+.databox .graphok {
+	background:#0d0;
+}
+.databox .graphwarn {
+	background:yellow;
+}
+.databox .grapherror {
+	background:red;
+}
+
+/* modifier for graph* classes, when inside a "status box" */
+.statusbox .datavalue {
+	width:60px;
+	text-align:center;
+	font-weight:Bold;
+}
+
+#sysinfo table th {
+	text-align:right;
+}
+
+
+#syslog ul {
+	list-style-type:none;
+	padding-left:0;
+	margin:0;
+}
+#syslog ul li {
+	position:relative;
+	margin-bottom:0.2em;
+	border-bottom:1px dashed #ccc;
+	margin-top:1px;
+	color:#333;
+}
+#syslog ul li>div {
+    padding-left:2px;
+}
+#syslog ul li .notification_buttons {
+    position:absolute;
+	right:0;
+	top:0;
+}
+#syslog ul li .notification_buttons a {
+	cursor:pointer;
+}
+#syslog ul li.notify_critical>div, #syslog ul li.notify_security>div {
+	/*background:#F7181C;*/
+	background:#f6921d;
+}
+#syslog ul li.notify_critical h4, #syslog ul li.notify_security h4 {
+	color:white;
+}
+/*
+
+/*
+#syslog .notify_ignore_btn {
+	background-image:url(images/notify_delete.png);
+	background-repeat:no-repeat;
+	width:16px;
+	height:16px;
+	display:inline;
+}
+*/
+
+#syslog h4 {
+	margin:0;
+	font-weight:normal;
+}
+#syslog h4 span {
+	cursor:pointer;
+}
+/* hide details by default */
+#syslog div.syslog_detail {
+	display:none;
+	font-size:75%;
+	height:7em;
+	overflow:auto;
+}
+#syslog div.syslog_detail span {
+	font-style:italic;
+}
+

Added: freepbx-modules/trunk/modules/dashboard/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/functions.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/functions.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,3 @@
+<?php /* $Id: functions.inc.php 2188 2006-07-27 02:21:52Z p_lindheimer $ */
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/images/dashboard-sysinfo.png
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/images/dashboard-sysinfo.png?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/dashboard/images/dashboard-sysinfo.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: freepbx-modules/trunk/modules/dashboard/images/notify_critical.png
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/images/notify_critical.png?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/dashboard/images/notify_critical.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: freepbx-modules/trunk/modules/dashboard/images/notify_delete.png
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/images/notify_delete.png?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/dashboard/images/notify_delete.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: freepbx-modules/trunk/modules/dashboard/images/notify_error.png
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/images/notify_error.png?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/dashboard/images/notify_error.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: freepbx-modules/trunk/modules/dashboard/images/notify_notice.png
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/images/notify_notice.png?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/dashboard/images/notify_notice.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: freepbx-modules/trunk/modules/dashboard/images/notify_security.png
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/images/notify_security.png?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/dashboard/images/notify_security.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: freepbx-modules/trunk/modules/dashboard/images/notify_update.png
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/images/notify_update.png?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/dashboard/images/notify_update.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: freepbx-modules/trunk/modules/dashboard/images/notify_warning.png
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/images/notify_warning.png?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/dashboard/images/notify_warning.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: freepbx-modules/trunk/modules/dashboard/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/module.xml?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/module.xml (added)
+++ freepbx-modules/trunk/modules/dashboard/module.xml Mon Apr  7 13:18:05 2008
@@ -1,0 +1,41 @@
+<module>
+	<rawname>dashboard</rawname>
+	<name>System Dashboard</name>
+	<version>0.3.3.2</version>
+	<candisable>no</candisable>
+	<canuninstall>no</canuninstall>
+	<type>tool</type>
+	<category>Basic</category>
+	<description>
+		Provides a system information dashboard, showing information about Calls, CPU, Memory, Disks, Network, and processes.
+	</description>
+	<menuitems>
+		<dashboard1 display="index" type="tool" category="Admin" sort="-10" access="all">FreePBX System Status</dashboard1>
+		<dashboard2 display="index" type="setup" category="Admin" sort="-10" access="all">FreePBX System Status</dashboard2>
+	</menuitems>
+	<depends>
+		<version>2.3.0beta2</version>
+	</depends>
+	<changelog>
+		*0.3.3.2* #2469 fix division my zero in cpu usage
+		*0.3.3.1* Cosmetic fix (#2278 - long mount point paths)
+		*0.3.3* Improved detection of webserver failing, More MySQL detection fixes
+		*0.3.2.1* #2246 make FreePBX Connections visible, #2250 check for SSHPORT
+		*0.3.2* Allow mysql server to be on another host/port (#2229), fix image path problem
+		*0.3.1* Fix issue with miscounting total registrations, minor styling details
+		*0.3* Show IP phones and trunks separately (#2209)
+		*0.2.5.4* make always accessible even in database mode, fix minor javascript bug
+		*0.2.5.3* remove deprecated javascript call
+		*0.2.5.2* #2194 don't fail when Asterisk is not running
+		*0.2.5.1* disable debug logging, make uninstallable
+		*0.2.5* #2142 fix online phones for Asterisk 1.4 format, #2140 divide by 0 again
+		*0.2.4* #2133 again, #2140 divide by 0, #2141 with temp log to determine real issue
+		*0.2.3* #2133 fixed number format error resulting in bogus percentage displays
+		*0.2.2* #2131 fix Undefined Index warnings
+		*0.2.1* make module permanent, should not be able to disable
+		*0.2.0* Add real-time updates
+		*0.1.0* Initial release
+	</changelog>
+	<location>release/2.4/dashboard-0.3.3.2.tgz</location>
+	<md5sum>913befd1d633fa4f884ec409db410a71</md5sum>
+</module>

Added: freepbx-modules/trunk/modules/dashboard/page.index.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/page.index.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/page.index.php (added)
+++ freepbx-modules/trunk/modules/dashboard/page.index.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,714 @@
+<?php /* $Id: page.parking.php 2243 2006-08-12 17:13:17Z p_lindheimer $ */
+//Copyright (C) 2006 Astrogen LLC 
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+$dashboard_debug = false;
+
+$dispnum = 'sysinfo'; //used for switch on config.php
+$action = isset($_REQUEST['action'])?$_REQUEST['action']:'';
+
+$quietmode = isset($_REQUEST['quietmode'])?$_REQUEST['quietmode']:'';
+$info = isset($_REQUEST['info'])?$_REQUEST['info']:false;
+
+$title="freePBX: Sysinfo Info";
+$message="System Info";
+
+if (isset($_REQUEST['showall'])) {
+	$_SESSION['syslog_showall'] = (bool)$_REQUEST['showall'];
+}
+
+//require_once('functions.inc.php');
+
+define('BAR_WIDTH_LEFT', 400);
+define('BAR_WIDTH_RIGHT', 200);
+
+// AJAX update intervals (in seconds)
+define('STATS_UPDATE_TIME', 6); // update interval for system uptime information
+define('INFO_UPDATE_TIME', 30); // update interval for system uptime information
+
+/** draw_graph
+ *  draw a bar graph
+ *
+ *  $text         Title of text
+ *  $real_units   Units to display
+ *  $val          Value to graph
+ *  $total        Total of graph
+ *  $classes      CSS classes to use based on value percent
+ *  $show_percent If results should be shown as percent
+ *  $total_width  Width of graph
+ */
+
+function draw_graph($text, $real_units, $val, $total = 100, $classes = null, $show_percent = true, $total_width = 200) {
+	if ($classes == null) {
+		$classes = array(
+			0=>'graphok',
+			70=>'graphwarn',
+			90=>'grapherror',
+		);
+	}
+
+	$chars_per_pixel = 7;
+	if (strlen($text) * $chars_per_pixel > $total_width - 35) {
+		$text_trimmed = substr($text,0, floor(($total_width - 35) / $chars_per_pixel)).'..';
+	} else {
+		$text_trimmed = $text;
+	}
+
+	$clean_val = preg_replace("/[^0-9\.]*/","",$val);
+
+	if ($total == 0) {
+		$percent = ($clean_val == 0) ? 0 : 100;
+	} else {
+		$percent = round($clean_val/$total*100);
+	}
+	
+	$graph_class = false;
+	foreach ($classes as $limit=>$class) {
+		if (!$graph_class) {
+			$graph_class = $class;
+		}
+		if ($limit <= $percent) {
+			$graph_class = $class;
+		} else {
+			break;
+		}
+	}
+	$width = $total_width * ($percent/100);
+	if ($width > $total_width) { 
+		$width = $total_width;
+	}
+	
+	$tooltip = $text.": ".$val.$real_units." / ".$total.$real_units." (".$percent."%)";
+	$display_value = ($show_percent ? $percent."%" : $val.$real_units); 
+	
+	$out = "<div class=\"databox graphbox\" style=\"width:".$total_width."px;\" title=\"".$tooltip."\">\n";
+	$out .= " <div class=\"bargraph ".$graph_class."\" style=\"width:".$width."px;\"></div>\n";
+	$out .= " <div class=\"dataname\">".$text_trimmed."</div>\n";
+	$out .= " <div class=\"datavalue\">".$display_value."</div>\n";
+	$out .= "</div>\n";
+	
+	return $out;
+}
+
+function draw_status_box($text, $status, $tooltip = false, $total_width = 200) {
+	switch ($status) {
+		case "ok":
+			$status_text = _("OK");
+			$class = "graphok";
+		break;
+		case "warn":
+			$status_text = _("Warn");
+			$class = "graphwarn";
+		break;
+		case "error":
+			$status_text = _("ERROR");
+			$class = "grapherror";
+		break;
+		case "disabled":
+			$status_text = "Disabled";
+			$class = "";
+		break;
+	}
+	if ($tooltip !== false) {
+		$status_text = '<a href="#" title="'.$tooltip.'">'.$status_text.'</a>';
+	}
+	
+	$out = "<div class=\"databox statusbox\" style=\"width:".$total_width."px;\">\n";
+	$out .= " <div class=\"dataname\">".$text."</div>\n";
+	$out .= " <div id=\"datavalue_".str_replace(" ","_",$text)."\" class=\"datavalue ".$class."\">".$status_text."</div>\n";
+	$out .= "</div>\n";
+	
+	return $out;
+}
+
+function draw_box($text, $value, $total_width = 200) {
+	$tooltip = $text.": ".$value;
+	
+	$out = "<div class=\"databox\" style=\"width:".$total_width."px;\">\n";
+	$out .= " <div class=\"dataname\">".$text."</div>\n";
+	$out .= " <div class=\"datavalue\"><a href=\"#\" title=\"".$tooltip."\">".$value."</a></div>\n";
+	$out .= "</div>\n";
+	
+	return $out;
+}
+
+function time_string($seconds) {
+    if ($seconds == 0) {
+        return "0 "._("minutes");
+    }
+
+    $minutes = floor($seconds / 60);
+    $seconds = $seconds % 60;
+
+    $hours = floor($minutes / 60);
+    $minutes = $minutes % 60;
+
+    $days = floor($hours / 24);
+    $hours = $hours % 24;
+	
+	$weeks = floor($days / 7);
+    $days = $days % 7;
+	
+	$output = array();
+	if ($weeks) { 
+		$output[] = $weeks." ".($weeks == 1 ? _("week") : _("weeks"));
+	}
+	if ($days) { 
+		$output[] = $days." ".($days == 1 ? _("days") : _("days"));
+	}
+	if ($hours) { 
+		$output[] = $hours." ".($hours == 1 ? _("hour") : _("hours"));
+	}
+	if ($minutes) { 
+		$output[] = $minutes." ".($minutes == 1 ? _("minute") : _("minutes"));
+	}
+	
+    return implode(", ",$output);
+}
+
+function show_sysstats() {
+	global $sysinfo;
+	$out = '';
+	
+	$out .= "<h3>"._("System Statistics")."</h3>";
+	$out .= "<h4>"._("Processor")."</h4>";
+	$loadavg = $sysinfo->loadavg(true);
+	$out .= draw_box(_("Load Average"), $loadavg['avg'][0]);
+	$out .= draw_graph(_("CPU"), "", number_format($loadavg['cpupercent'],2), 100);
+	
+	$out .= "<h4>"._("Memory")."</h4>";
+	$memory = $sysinfo->memory();
+	$app_memory = isset($memory["ram"]["app"]) ? $memory["ram"]["app"] : $memory["ram"]["total"] - $memory["ram"]["t_free"];
+	$out .= draw_graph(_("App Memory"), "MB", number_format($app_memory/1024,2), $memory["ram"]["total"]/1024);
+	$out .= draw_graph(_("Swap"), "MB", number_format(($memory["swap"]["total"]-$memory["swap"]["free"])/1024,2), $memory["swap"]["total"]/1024);
+	
+	$out .= "<h4>"._("Disks")."</h4>";
+	foreach ($sysinfo->filesystems() as $fs) {
+		$out .= draw_graph($fs["mount"], "GB", number_format($fs["used"]/1024/1024, 2), $fs["size"]/1024/1024);
+	}
+	
+	$out .= "<h4>"._("Networks")."</h4>";
+	foreach ($sysinfo->network() as $net_name=>$net) {
+		$net_name = trim($net_name);
+		if ($net_name == 'lo' || $net_name == 'sit0') continue;
+		
+		$tx = new average_rate_calculator($_SESSION["netstats"][$net_name]["tx"], 10); // 30s max age
+		$rx = new average_rate_calculator($_SESSION["netstats"][$net_name]["rx"], 10); // 30s max age
+		
+		$rx->add( $net["rx_bytes"] );
+		$tx->add( $net["tx_bytes"] );
+		
+		$out .= draw_box($net_name." "._("receive"), number_format($rx->average()/1000,2)." KB/s");
+		$out .= draw_box($net_name." "._("transmit"), number_format($tx->average()/1000,2)." KB/s");
+	}
+	return $out;
+}
+
+function show_aststats() {
+	global $amp_conf;
+	global $astinfo;
+	$out = '';
+	
+	$channels = $astinfo->get_channel_totals();
+	// figure out max_calls
+	
+	// guess at the max calls: number of users
+	if (!isset($_SESSION["calculated_max_calls"])) {
+		// set max calls to either MAXCALLS in amportal.conf, or the number of users in the system
+		if (isset($amp_conf['MAXCALLS'])) {
+			$_SESSION["calculated_max_calls"] = $amp_conf["MAXCALLS"];
+		} else if (function_exists('core_users_list')) {
+			$_SESSION["calculated_max_calls"] = count(core_users_list());
+		} else {
+			$_SESSION["calculated_max_calls"] = 1;
+		}
+	}
+	// we currently see more calls than we guessed, increase it
+	if ($channels['total_calls'] > $_SESSION["calculated_max_calls"]) {
+		$_SESSION["calculated_max_calls"] = $channels['total_calls'];
+	}
+	$max_calls = $_SESSION["calculated_max_calls"];
+	
+	$classes = array(0=>'graphok');
+	$max_chans = $max_calls * 2;
+	
+	$out .= "<h3>"._("FreePBX Statistics")."</h3>";
+	$out .= draw_graph(_('Total active calls'), '', $channels['total_calls'], $max_calls, $classes , false, BAR_WIDTH_LEFT);
+	$out .= draw_graph(_('Internal calls'), '', $channels['internal_calls'], $max_calls, $classes , false, BAR_WIDTH_LEFT);
+	$out .= draw_graph(_('External calls'), '', $channels['external_calls'], $max_calls, $classes , false, BAR_WIDTH_LEFT);
+	$out .= draw_graph(_('Total active channels'), '', $channels['total_channels'], $max_chans, $classes , false, BAR_WIDTH_LEFT);
+	
+	$out .= "<h4>"._("FreePBX Connections")."</h4>";
+	
+	if (function_exists('core_trunks_list')) {
+		$trunks = core_trunks_list(true);
+	} else {
+		$trunks = false;
+	}
+	$conns = $astinfo->get_connections( $trunks );
+
+	if ($conns['users_total'] > 0) {
+		$out .= draw_graph(_('IP Phones Online'), '', $conns['users_online'], $conns['users_total'], $classes, false, BAR_WIDTH_LEFT);
+	}
+	if ($conns['trunks_total'] > 0) {
+		$out .= draw_graph(_('IP Trunks Online'), '', $conns['trunks_online'], $conns['trunks_total'], $classes, false, BAR_WIDTH_LEFT);
+	}
+	if ($conns['registrations_total'] > 0) {
+		$out .= draw_graph(_('IP Trunk Registrations'), '', $conns['registrations_online'], $conns['registrations_total'], $classes, false, BAR_WIDTH_LEFT);
+	}
+
+	return $out;
+}
+
+function show_sysinfo() {
+	global $sysinfo;
+	global $astinfo;
+	$out = "<h3>"._("Uptime")."</h3></br>";
+	$out .= '<table>';
+	/*
+	$out .= '<tr><th>Distro:</th><td>'.$sysinfo->distro().'</td></tr>';
+	$out .= '<tr><th>Kernel:</th><td>'.$sysinfo->kernel().'</td></tr>';
+	$cpu = $sysinfo->cpu_info();
+	$out .= '<tr><th>CPU:</th><td>'.$cpu['model'].' '.$cpu['cpuspeed'].'</td></tr>';
+	*/
+	
+	$out .= '<tr><th>'._('System Uptime').':</th><td>'.time_string($sysinfo->uptime()).'</td></tr>';
+	$ast_uptime = $astinfo->get_uptime();
+	if (empty($ast_uptime['system'])) {
+		$ast_uptime['system'] = time_string(0);
+	}
+	if (empty($ast_uptime['reload'])) {
+		$ast_uptime['reload'] = time_string(0);
+	}
+	$out .= '<tr><th>'._('Asterisk Uptime').':</th><td>'.$ast_uptime['system'].'</td></tr>';
+	$out .= '<tr><th>'._('Last Reload').':</th><td>'.$ast_uptime['reload'].'</td></tr>';
+	
+	$out .= '</table>';
+	return $out;
+}
+
+function show_procinfo() {
+	global $procinfo;
+	global $astinfo;
+	global $amp_conf;
+	$out = '';
+	
+	$out .= "<h3>"._("Server Status")."</h3>";
+	// asterisk
+	if ($astver = $astinfo->check_asterisk()) {
+		$out .= draw_status_box(_("Asterisk"), "ok", _('Asterisk is running: '.$astver));
+	} else {
+		$out .= draw_status_box(_("Asterisk"), "error", _('Asterisk is not running, this is a critical service!'));
+	}
+	
+	// asterisk proxy (optionally)
+	if (isset($amp_conf['ASTMANAGERPROXYPORT'])) {
+		if ($procinfo->check_port($amp_conf['ASTMANAGERPROXYPORT'])) {
+			$out .= draw_status_box(_("Manager Proxy"), "ok", _('Asterisk Manager Proxy is running'));
+		} else {
+			$out .= draw_status_box(_("Manager Proxy"), "warn", _('Asterisk Manager Proxy is not running, FreePBX will fall back to using Asterisk directly, which may result in poor performance'));
+		}		
+	}
+	
+	// fop
+	if ($procinfo->check_fop_server()) {
+		$out .= draw_status_box(_("Op Panel"), "ok", _('FOP Operator Panel Server is running'));
+	} else {
+		if (isset($amp_conf['FOPRUN']) && $amp_conf['FOPRUN']) {
+			// it should be running
+			$out .= draw_status_box(_("Op Panel"), "warn", _('FOP Operator Panel Server is not running, you will not be able to use the operator panel, but the system will run fine without it.'));
+		} else {
+			$out .= draw_status_box(_("Op Panel"), "disabled", _('FOP Operator Panel is disabled in amportal.conf'));
+		}
+	}
+	
+	// mysql
+	if ($amp_conf['AMPDBENGINE'] == "mysql") {
+		/* this is silly- it's always running, if the web interface loads
+		if ($procinfo->check_mysql($amp_conf['AMPDBHOST'])) {
+			$out .= draw_status_box(_("MySQL"), "ok", _('MySQL Server is running'));
+		} else {
+			$out .= draw_status_box(_("MySQL"), "error", _('MySQL Server is not running, this is a critical service for the web interface and call logs!'));
+		}
+		*/
+		$out .= draw_status_box(_("MySQL"), "ok", _('MySQL Server is running'));
+	}
+	
+	// web always runs .. HOWEVER, we can turn it off with dhtml
+	$out .= draw_status_box(_("Web Server"), "ok", _('Web Server is running'));
+	
+	// ssh	
+	$ssh_port = (isset($amp_conf['SSHPORT']) && ctype_digit($amp_conf['SSHPORT']) && ($amp_conf['SSHPORT'] > 0) && ($amp_conf['SSHPORT'] < 65536))?$amp_conf['SSHPORT']:22;
+	if ($procinfo->check_port($ssh_port)) {
+		$out .= draw_status_box(_("SSH Server"), "ok", _('SSH Server is running'));
+	} else {
+		$out .= draw_status_box(_("SSH Server"), "warn", _('SSH Server is not running, you will not be able to connect to the system console remotely'));
+	}
+	return $out;
+}
+
+function show_syslog(&$md5_checksum) {
+	global $db;
+	$out = '';
+	$checksum = '';
+
+	// notify_classes are also used as the image names
+	$notify_classes = array( 
+		NOTIFICATION_TYPE_CRITICAL => 'notify_critical',
+		NOTIFICATION_TYPE_SECURITY => 'notify_security',
+		NOTIFICATION_TYPE_UPDATE => 'notify_update',
+		NOTIFICATION_TYPE_ERROR => 'notify_error',
+		NOTIFICATION_TYPE_WARNING => 'notify_warning',
+		NOTIFICATION_TYPE_NOTICE => 'notify_notice',
+	);
+	$notify_descriptions = array(
+		NOTIFICATION_TYPE_CRITICAL => _('Critical Error'),
+		NOTIFICATION_TYPE_SECURITY => _('Security Update'),
+		NOTIFICATION_TYPE_UPDATE => _('Update'),
+		NOTIFICATION_TYPE_ERROR => _('Error'),
+		NOTIFICATION_TYPE_WARNING => _('Warning'),
+		NOTIFICATION_TYPE_NOTICE => _('Notice'),
+	);
+	
+	$notify =& notifications::create($db);
+	
+	$showall = (isset($_SESSION['syslog_showall']) ? $_SESSION['syslog_showall'] : false);
+	
+	$items = $notify->list_all($showall);
+
+	$out .= "<h3>"._("FreePBX Notices")."</h3>";
+	
+	if (count($items)) {
+		$out .= '<ul>';
+		foreach ($items as $item) {
+			$checksum .= $item['module'].$item['id']; // checksum, so it is only updated on the page if this has changed
+			
+			$domid = "notify_item_".str_replace(' ','_',$item['module']).'_'.str_replace(' ','_',$item['id']);
+			
+			$out .= '<li id="'.$domid.'" ';
+			if (isset($notify_classes[$item['level']])) {
+				$out .= ' class="'.$notify_classes[$item['level']].'"';
+			}
+			$out .= '><div>';
+
+			$out .= '<h4 class="syslog_text">';
+			$out .= '<span><img src="images/'.$notify_classes[$item['level']].'.png" alt="'.$notify_descriptions[$item['level']].'" title="'.$notify_descriptions[$item['level']].'" width="16" height="16" border="0" />&nbsp;';
+			$out .= $item['display_text'].'</span>';
+			$out .= '<div class="notification_buttons">';
+			if (isset($item['candelete']) && $item['candelete']) {
+				$out .= '<a class="notify_ignore_btn" title="'._('Delete this').'" '.
+				        'onclick="delete_notification(\''.$domid.'\', \''.$item['module'].'\', \''.$item['id'].'\');">'.
+				        '<img src="images/cancel.png" width="16" height="16" border="0" alt="'._('Delete this').'" /></a>';
+			}
+			if (!$item['reset']) {
+				$out .= '<a class="notify_ignore_btn" title="'._('Ignore this').'" '.
+				        'onclick="hide_notification(\''.$domid.'\', \''.$item['module'].'\', \''.$item['id'].'\');">'.
+				        '<img src="'.dirname($_SERVER['PHP_SELF']).'/images/notify_delete.png" width="16" height="16" border="0" alt="'._('Ignore this').'" /></a>';
+			}
+			$out .= '</div>';
+			$out .= '</h4>';
+			
+			$out .= '<div class="syslog_detail">';
+			$out .= nl2br($item['extended_text']);
+			$out .= '<br/><span>'.sprintf('Added %s ago', time_string(time() - $item['timestamp'])).'<br/>'.
+			        '('.$item['module'].'.'.$item['id'].')</span>';
+			$out .= '</div>';
+			
+			$out .= '</div></li>';
+		}
+		$out .= '</ul>';
+	} else {
+		if ($showall) {
+			$out .= _('No notifications');
+		} else {
+			$out .= _('No new notifications');
+		}
+	}
+	
+	$md5_checksum = md5($checksum);
+	
+	$out .= '<div id="syslog_button">';
+	if ($showall) {
+		$out .= '<a href="#" onclick="changeSyslog(0);">'._('show new').'</a>';
+	} else {
+		$out .= '<a href="#" onclick="changeSyslog(1);">'._('show all').'</a>';
+	}
+	$out .= '</div>';
+	return $out;
+}
+
+function do_syslog_ack() {	
+	global $db;
+	$notify =& notifications::create($db);
+	
+	if (isset($_REQUEST['module']) && $_REQUEST['id']) {
+		$notify->reset($_REQUEST['module'], $_REQUEST['id']);
+	}
+}
+function do_syslog_delete() {	
+	global $db;
+	$notify =& notifications::create($db);
+	
+	if (isset($_REQUEST['module']) && $_REQUEST['id']) {
+	var_dump($_REQUEST);
+		$notify->safe_delete($_REQUEST['module'], $_REQUEST['id']);
+	}
+}
+
+/********************************************************************************************/
+
+
+define("IN_PHPSYSINFO", "1");
+define("APP_ROOT", dirname(__FILE__).'/phpsysinfo');
+include APP_ROOT."/common_functions.php";
+include APP_ROOT."/class.".PHP_OS.".inc.php";
+include_once "common/json.inc.php";
+include dirname(__FILE__)."/class.astinfo.php";
+include dirname(__FILE__)."/class.average_rate_calculator.php";
+include dirname(__FILE__)."/class.procinfo.php";
+include dirname(__FILE__)."/class.error.inc.php";
+
+$error = new Error;
+
+
+$sysinfo = new sysinfo;
+$astinfo = new astinfo($astman);
+$procinfo = new procinfo;
+
+
+if (!$quietmode) {
+	?>
+	
+	<script language="javascript">
+	$(document).ready(function(){
+		$.ajaxTimeout( 20000 );
+		scheduleInfoUpdate();
+		scheduleStatsUpdate();
+		
+		makeSyslogClickable();
+	});
+	
+	function makeSyslogClickable() {
+		$('#syslog h4 span').click(function() {
+			$(this).parent().next('div').slideToggle('fast');
+		});
+	}
+	
+	var syslog_md5;
+	var webserver_fail = 0;
+	var info_timer = null;
+	var stats_timer = null;
+
+	function updateFailed(reqObj, status) {
+		// stop updating 
+		clearTimeout(stats_timer);
+		stats_timer = null;
+		clearTimeout(info_timer);
+		info_timer = null;
+
+		webserver_fail += 1;
+		webobj = $('#datavalue_Web_Server')
+
+		if (webserver_fail == 1) {
+			webobj.text("Timeout");
+			webobj.removeClass("graphok");
+			webobj.addClass("graphwarn");	
+		} else {
+			webobj.text("ERROR");
+			webobj.removeClass("graphok");
+			webobj.removeClass("graphwarn");
+			webobj.addClass("grapherror");
+		}
+		scheduleInfoUpdate();
+	}
+
+
+	function updateInfo() {
+		$.ajax({
+			type: 'GET',
+			url: "<?php echo $_SERVER["PHP_SELF"]; ?>?type=tool&display=<?php echo $module_page; ?>&quietmode=1&info=info", 
+			dataType: 'json',
+			success: function(data) {
+				$('#procinfo').html(data.procinfo);
+				$('#sysinfo').html(data.sysinfo);
+				// only update syslog div if the md5 has changed
+				if (syslog_md5 != data.syslog_md5) {
+					$('#syslog').html(data.syslog);
+					makeSyslogClickable();
+					syslog_md5 = data.syslog_md5;
+				}
+
+				// webserver is ok
+				webserver_fail = 0;
+
+				scheduleInfoUpdate();
+				if (stats_timer == null) {
+					// restart stats updates
+					scheduleStatsUpdate();
+				}
+			},
+			error: updateFailed
+		});
+	}
+	function scheduleInfoUpdate() {
+		info_timer = setTimeout('updateInfo();',<?php echo INFO_UPDATE_TIME; ?>000);
+	}
+	
+	
+	function updateStats() {
+		$.ajax({
+			type: 'GET',
+			url: "<?php echo $_SERVER["PHP_SELF"]; ?>?type=tool&display=<?php echo $module_page; ?>&quietmode=1&info=stats", 
+			dataType: 'json',
+			success: function(data) {
+				$('#sysstats').html(data.sysstats);
+				$('#aststats').html(data.aststats);
+				scheduleStatsUpdate();
+			},
+			error: updateFailed
+		});
+	}
+	function scheduleStatsUpdate() {
+		stats_timer = setTimeout('updateStats();',<?php echo STATS_UPDATE_TIME; ?>000);
+	}
+	
+	
+	function changeSyslog(showall) {
+		$('#syslog_button').text('<?php echo _('loading...'); ?>');
+		$('#syslog').load("<?php echo $_SERVER["PHP_SELF"]; ?>?type=tool&display=<?php echo $module_page; ?>&quietmode=1&info=syslog&showall="+showall,{}, function() {
+			makeSyslogClickable();
+		});
+	}
+
+	function hide_notification(domid, module, id) {
+		$('#'+domid).fadeOut('slow');
+		$.post('config.php', {display:'<?php echo $module_page; ?>', quietmode:1, info:'syslog_ack', module:module, id:id});
+	}
+	function delete_notification(domid, module, id) {
+		$('#'+domid).fadeOut('slow');
+		$.post('config.php', {display:'<?php echo $module_page; ?>', quietmode:1, info:'syslog_delete', module:module, id:id});
+	}
+	</script>
+
+	<h2>FreePBX System Status</h2>
+	</div>
+	<div id="dashboard">
+	<?php
+	echo '<div id="sysinfo-left">';
+	
+	// regular page
+	echo '<div id="syslog" class="infobox">';
+	echo show_syslog($syslog_md5);
+	// syslog_md5 is used by javascript updateInfo() to determine if the syslog div contents have changed
+	echo '<script type="text/javascript"> syslog_md5 = "'.$syslog_md5.'"; </script>';
+	//echo "log goes here<br/><br/><br/>";
+	echo '</div>';
+	
+	echo '<div id="aststats" class="infobox">';
+	echo show_aststats();
+	echo '</div>';
+	
+	
+	echo '<div id="sysinfo" class="infobox">';
+	echo show_sysinfo();
+	echo '</div>';
+	
+	
+	
+	echo '</div><div id="sysinfo-right">';
+	
+	
+	
+	echo '<div id="sysstats" class="infobox">';
+	echo show_sysstats();
+	echo '</div>';
+	
+	echo '<div id="procinfo" class="infobox">';
+	echo show_procinfo();
+	echo '</div>';
+	
+	echo '<div style="clear:both;"></div>';
+	
+	echo '</div></div>'; // #sysinfo, #sysinfo-right
+	
+	echo '<div class="content">';
+
+	if($dashboard_debug && $error->ErrorsExist()) {
+		$fh = fopen($amp_conf['ASTLOGDIR']."/dashboard-error.log","a");
+		fwrite($fh, $error->ErrorsAsText());
+		fclose($fh);
+	}           
+
+} else {
+	// Handle AJAX updates
+	
+	switch ($info) {
+		case "sysstats":
+			echo show_sysstats();
+		break;
+		case "aststats":
+			echo show_aststats();
+		break;
+		case "procinfo":
+			echo show_procinfo();
+		break;
+		case 'sysinfo':
+			echo show_sysinfo();
+		break;
+		case 'syslog':
+			echo show_syslog($syslog_md5);	
+			// syslog_md5 is used by javascript updateInfo() to determine if the syslog div contents have changed
+			echo '<script type="text/javascript"> syslog_md5 = "'.$syslog_md5.'"; </script>';
+		break;
+		case 'syslog_ack':
+			do_syslog_ack();
+		break;
+		case 'syslog_delete':
+			do_syslog_delete();
+		break;
+		
+		case 'info':
+			$json = new Services_JSON();
+			echo $json->encode(
+				array(
+					'procinfo'=>show_procinfo(),
+					'sysinfo'=>show_sysinfo(),
+					'syslog'=>show_syslog($syslog_md5),
+					'syslog_md5'=>$syslog_md5,
+				)
+			);
+		break;
+		case 'stats':
+			$json = new Services_JSON();
+			echo $json->encode(
+				array(
+					'sysstats'=>show_sysstats(),
+					'aststats'=>show_aststats(),
+				)
+			);
+		break;
+		case 'all':
+			$json = new Services_JSON();
+			echo $json->encode(
+				array(
+					'sysstats'=>show_sysstats(),
+					'aststats'=>show_aststats(),
+					'procinfo'=>show_procinfo(),
+					'sysinfo'=>show_sysinfo(),
+					'syslog'=>show_syslog(),
+				)
+			);
+		break;
+	}
+}
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.BSD.common.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.BSD.common.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.BSD.common.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.BSD.common.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,298 @@
+<?php 
+
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+
+// 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.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// $Id: class.BSD.common.inc.php,v 1.50 2006/04/22 14:35:57 bigmichi1 Exp $
+
+if (!defined('IN_PHPSYSINFO')) {
+    die("No Hacking");
+}
+
+require_once(APP_ROOT . '/class.parseProgs.inc.php');
+
+class bsd_common {
+  var $dmesg; 
+  var $parser;
+  // Our constructor
+  // this function is run on the initialization of this class
+  function bsd_common () {
+    $this->parser = new Parser();
+    $this->parser->df_param = "";    
+  } 
+  
+  // read /var/run/dmesg.boot, but only if we haven't already.
+  function read_dmesg () {
+    if (! $this->dmesg) {
+      $parts = explode("rebooting", rfts( '/var/run/dmesg.boot' ) );
+      $this->dmesg = explode("\n", $parts[count($parts) - 1]);
+    } 
+    return $this->dmesg;
+  } 
+  
+  // grabs a key from sysctl(8)
+  function grab_key ($key) {
+    return execute_program('sysctl', "-n $key");
+  } 
+  // get our apache SERVER_NAME or vhost
+  function hostname () {
+    if (!($result = getenv('SERVER_NAME'))) {
+      $result = "N.A.";
+    } 
+    return $result;
+  } 
+  // get our canonical hostname
+  function chostname () {
+    return execute_program('hostname');
+  } 
+  // get the IP address of our canonical hostname
+  function ip_addr () {
+    if (!($result = getenv('SERVER_ADDR'))) {
+      $result = gethostbyname($this->chostname());
+    } 
+    return $result;
+  } 
+
+  function kernel () {
+    $s = $this->grab_key('kern.version');
+    $a = explode(':', $s);
+    return $a[0] . $a[1] . ':' . $a[2];
+  } 
+
+  function uptime () {
+    $result = $this->get_sys_ticks();
+
+    return $result;
+  } 
+
+  function users () {
+    return execute_program('who', '| wc -l');
+  } 
+
+  function loadavg ($bar = false) {
+    $s = $this->grab_key('vm.loadavg');
+    $s = ereg_replace('{ ', '', $s);
+    $s = ereg_replace(' }', '', $s);
+    $results['avg'] = explode(' ', $s);
+
+    if ($bar) {
+      if ($fd = $this->grab_key('kern.cp_time')) {
+        // Find out the CPU load
+        // user + sys = load
+        // total = total
+	preg_match($this->cpu_regexp2, $fd, $res );
+        $load = $res[2] + $res[3] + $res[4];		// cpu.user + cpu.sys
+        $total = $res[2] + $res[3] + $res[4] + $res[5];	// cpu.total
+
+        // we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
+        sleep(1);
+        $fd = $this->grab_key('kern.cp_time');
+	preg_match($this->cpu_regexp2, $fd, $res );
+        $load2 = $res[2] + $res[3] + $res[4];
+        $total2 = $res[2] + $res[3] + $res[4] + $res[5];
+        $results['cpupercent'] = (100*($load2 - $load)) / ($total2 - $total);
+      }
+    }
+    return $results;
+  } 
+
+  function cpu_info () {
+    $results = array();
+    $ar_buf = array();
+
+    $results['model'] = $this->grab_key('hw.model');
+    $results['cpus'] = $this->grab_key('hw.ncpu');
+
+    for ($i = 0, $max = count($this->read_dmesg()); $i < $max; $i++) {
+      $buf = $this->dmesg[$i];
+      if (preg_match("/$this->cpu_regexp/", $buf, $ar_buf)) {
+        $results['cpuspeed'] = round($ar_buf[2]);
+        break;
+      } 
+    } 
+    return $results;
+  } 
+  // get the scsi device information out of dmesg
+  function scsi () {
+    $results = array();
+    $ar_buf = array();
+
+    for ($i = 0, $max = count($this->read_dmesg()); $i < $max; $i++) {
+      $buf = $this->dmesg[$i];
+
+      if (preg_match("/$this->scsi_regexp1/", $buf, $ar_buf)) {
+        $s = $ar_buf[1];
+        $results[$s]['model'] = $ar_buf[2];
+        $results[$s]['media'] = 'Hard Disk';
+      } elseif (preg_match("/$this->scsi_regexp2/", $buf, $ar_buf)) {
+        $s = $ar_buf[1];
+        $results[$s]['capacity'] = $ar_buf[2] * 2048 * 1.049;
+      }
+    } 
+    // return array_values(array_unique($results));
+    // 1. more useful to have device names
+    // 2. php 4.1.1 array_unique() deletes non-unique values.
+    asort($results);
+    return $results;
+  } 
+
+  // get the pci device information out of dmesg
+  function pci () {
+    $results = array();
+
+    if( !( is_array($results = $this->parser->parse_lspci()) || is_array($results = $this->parser->parse_pciconf() ))) {
+        for ($i = 0, $s = 0; $i < count($this->read_dmesg()); $i++) {
+	    $buf = $this->dmesg[$i];
+	    if(!isset($this->pci_regexp1) && !isset($this->pci_regexp2)) {
+	        $this->pci_regexp1 = '/(.*): <(.*)>(.*) pci[0-9]$/';
+	        $this->pci_regexp2 = '/(.*): <(.*)>.* at [.0-9]+ irq/';
+	    }
+	    if (preg_match($this->pci_regexp1, $buf, $ar_buf)) {
+	        $results[$s++] = $ar_buf[1] . ": " . $ar_buf[2];
+	    } elseif (preg_match($this->pci_regexp2, $buf, $ar_buf)) {
+	        $results[$s++] = $ar_buf[1] . ": " . $ar_buf[2];
+	    }
+	} 
+    	asort($results);
+    }
+    return $results;
+  } 
+
+  // get the ide device information out of dmesg
+  function ide () {
+    $results = array();
+
+    $s = 0;
+    for ($i = 0, $max = count($this->read_dmesg()); $i < $max; $i++) {
+      $buf = $this->dmesg[$i];
+
+      if (preg_match('/^(ad[0-9]+): (.*)MB <(.*)> (.*) (.*)/', $buf, $ar_buf)) {
+        $s = $ar_buf[1];
+        $results[$s]['model'] = $ar_buf[3];
+        $results[$s]['media'] = 'Hard Disk';
+        $results[$s]['capacity'] = $ar_buf[2] * 2048 * 1.049;
+      } elseif (preg_match('/^(acd[0-9]+): (.*) <(.*)> (.*)/', $buf, $ar_buf)) {
+        $s = $ar_buf[1];
+        $results[$s]['model'] = $ar_buf[3];
+        $results[$s]['media'] = 'CD-ROM';
+      }
+    } 
+    // return array_values(array_unique($results));
+    // 1. more useful to have device names
+    // 2. php 4.1.1 array_unique() deletes non-unique values.
+    asort($results);
+    return $results;
+  } 
+
+  // place holder function until we add acual usb detection
+  function usb () {
+    return array();
+  } 
+
+  function sbus () {
+    $results = array();
+    $_results[0] = "";
+    // TODO. Nothing here yet. Move along.
+    $results = $_results;
+    return $results;
+  }
+
+  function memory () {
+    $s = $this->grab_key('hw.physmem');
+
+    if (PHP_OS == 'FreeBSD' || PHP_OS == 'OpenBSD') {
+      // vmstat on fbsd 4.4 or greater outputs kbytes not hw.pagesize
+      // I should probably add some version checking here, but for now
+      // we only support fbsd 4.4
+      $pagesize = 1024;
+    } else {
+      $pagesize = $this->grab_key('hw.pagesize');
+    } 
+
+    $results['ram'] = array();
+
+    $pstat = execute_program('vmstat');
+    $lines = split("\n", $pstat);
+    for ($i = 0, $max = sizeof($lines); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $lines[$i], 19);
+      if ($i == 2) {
+        if(PHP_OS == 'NetBSD') {
+	    $results['ram']['free'] = $ar_buf[5];
+	} else {
+    	    $results['ram']['free'] = $ar_buf[5] * $pagesize / 1024;
+	}
+      } 
+    } 
+
+    $results['ram']['total'] = $s / 1024;
+    $results['ram']['shared'] = 0;
+    $results['ram']['buffers'] = 0;
+    $results['ram']['used'] = $results['ram']['total'] - $results['ram']['free'];
+    $results['ram']['cached'] = 0;
+    $results['ram']['t_used'] = $results['ram']['used'];
+    $results['ram']['t_free'] = $results['ram']['free'];
+
+    $results['ram']['percent'] = round(($results['ram']['used'] * 100) / $results['ram']['total']);
+
+    if (PHP_OS == 'OpenBSD' || PHP_OS == 'NetBSD') {
+      $pstat = execute_program('swapctl', '-l -k');
+    } else {
+      $pstat = execute_program('swapinfo', '-k');
+    } 
+
+    $lines = split("\n", $pstat);
+
+    $results['swap']['total'] = 0;
+    $results['swap']['used'] = 0;
+    $results['swap']['free'] = 0;
+
+    for ($i = 1, $max = sizeof($lines); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $lines[$i], 6);
+
+      if ($ar_buf[0] != 'Total') {
+        $results['swap']['total'] = $results['swap']['total'] + $ar_buf[1];
+        $results['swap']['used'] = $results['swap']['used'] + $ar_buf[2];
+        $results['swap']['free'] = $results['swap']['free'] + $ar_buf[3];
+
+        $results['devswap'][$i - 1] = array();
+        $results['devswap'][$i - 1]['dev'] = $ar_buf[0];
+        $results['devswap'][$i - 1]['total'] = $ar_buf[1];
+        $results['devswap'][$i - 1]['used'] = $ar_buf[2];
+        $results['devswap'][$i - 1]['free'] = ($results['devswap'][$i - 1]['total'] - $results['devswap'][$i - 1]['used']);
+        $results['devswap'][$i - 1]['percent'] = $ar_buf[2] > 0 ? round(($ar_buf[2] * 100) / $ar_buf[1]) : 0;
+      }
+    } 
+    $results['swap']['percent'] = round(($results['swap']['used'] * 100) / $results['swap']['total']);
+
+    if( is_callable( array( 'sysinfo', 'memory_additional' ) ) ) {
+        $results = $this->memory_additional( $results );
+    }
+    return $results;
+  } 
+
+  function filesystems () {
+    return $this->parser->parse_filesystems();
+  }
+
+  function distro () { 
+    $distro = execute_program('uname', '-s');                             
+    $result = $distro;
+    return($result);               
+  }
+} 
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.Darwin.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.Darwin.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.Darwin.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.Darwin.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,237 @@
+<?php 
+
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+
+// 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.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// $Id: class.Darwin.inc.php,v 1.26 2006/04/15 21:42:20 bigmichi1 Exp $
+if (!defined('IN_PHPSYSINFO')) {
+    die("No Hacking");
+}
+
+require_once(APP_ROOT . '/class.BSD.common.inc.php');
+
+$error->addError("WARN", "The Darwin version of phpSysInfo is work in progress, some things currently don't work");
+
+class sysinfo extends bsd_common {
+  var $cpu_regexp;
+  var $scsi_regexp; 
+  // Our contstructor
+  // this function is run on the initialization of this class
+  function sysinfo () {
+    // $this->cpu_regexp = "CPU: (.*) \((.*)-MHz (.*)\)";
+    // $this->scsi_regexp1 = "^(.*): <(.*)> .*SCSI.*device";
+    $this->cpu_regexp2 = "/(.*) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)/";
+  } 
+
+  function grab_key ($key) {
+    $s = execute_program('sysctl', $key);
+    $s = ereg_replace($key . ': ', '', $s);
+    $s = ereg_replace($key . ' = ', '', $s); // fix Apple set keys
+    
+    return $s;
+  } 
+
+  function grab_ioreg ($key) {
+    $s = execute_program('ioreg', '-cls "' . $key . '" | grep "' . $key . '"'); //ioreg -cls "$key" | grep "$key"
+    $s = ereg_replace('\|', '', $s);
+    $s = ereg_replace('\+\-\o', '', $s);
+    $s = ereg_replace('[ ]+', '', $s);
+    $s = ereg_replace('<[^>]+>', '', $s); // remove possible XML conflicts
+
+    return $s;
+  } 
+
+  function get_sys_ticks () {
+    $a = execute_program('sysctl', '-n kern.boottime'); // get boottime (value in seconds) 
+    $sys_ticks = time() - $a;
+
+    return $sys_ticks;
+  } 
+
+  function cpu_info () {
+    $results = array(); 
+    // $results['model'] = $this->grab_key('hw.model'); // need to expand this somehow...
+    // $results['model'] = $this->grab_key('hw.machine');
+    $results['model'] = ereg_replace('Processor type: ', '', execute_program('hostinfo', '| grep "Processor type"')); // get processor type
+    $results['cpus'] = $this->grab_key('hw.ncpu');
+    $results['cpuspeed'] = round($this->grab_key('hw.cpufrequency') / 1000000); // return cpu speed - Mhz
+    $results['busspeed'] = round($this->grab_key('hw.busfrequency') / 1000000); // return bus speed - Mhz
+    $results['cache'] = round($this->grab_key('hw.l2cachesize') / 1024); // return l2 cache
+
+    if (($this->grab_key('hw.model') == "PowerMac3,6") && ($results['cpus'] == "2")) { $results['model'] = 'Dual G4 - (PowerPC 7450)';} // is Dual G4
+    if (($this->grab_key('hw.model') == "PowerMac7,2") && ($results['cpus'] == "2")) { $results['model'] = 'Dual G5 - (PowerPC 970)';} // is Dual G5
+
+    return $results;
+  } 
+  // get the pci device information out of ioreg
+  function pci () {
+    $results = array();
+    $s = $this->grab_ioreg('IOPCIDevice');
+
+    $lines = split("\n", $s);
+    for ($i = 0, $max = sizeof($lines); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $lines[$i], 19);
+      $results[$i] = $ar_buf[0];
+    } 
+    asort($results);
+    return array_values(array_unique($results));
+  } 
+  // get the ide device information out of ioreg
+  function ide () {
+    $results = array(); 
+    // ioreg | grep "Media  <class IOMedia>"
+    $s = $this->grab_ioreg('IOATABlockStorageDevice'); 
+
+    $lines = split("\n", $s);
+    $j = 0;
+    for ($i = 0, $max = sizeof($lines); $i < $max; $i++) {
+      $ar_buf = preg_split("/\/\//", $lines[$i], 19);
+
+      if ($ar_buf[1] == 'class IOMedia' && preg_match('/Media/', $ar_buf[0])) {
+        $results[$j++]['model'] = $ar_buf[0];
+      } 
+    } 
+    asort($results);
+    return array_values(array_unique($results));
+  } 
+
+  function memory () {
+    $s = $this->grab_key('hw.memsize');
+
+    $results['ram'] = array();
+
+    $pstat = execute_program('vm_stat'); // use darwin's vm_stat
+    $lines = split("\n", $pstat);
+    for ($i = 0, $max = sizeof($lines); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $lines[$i], 19);
+
+      if ($i == 1) {
+        $results['ram']['free'] = $ar_buf[2] * 4; // calculate free memory from page sizes (each page = 4MB)
+      } 
+    } 
+
+    $results['ram']['total'] = $s / 1024;
+    $results['ram']['shared'] = 0;
+    $results['ram']['buffers'] = 0;
+    $results['ram']['used'] = $results['ram']['total'] - $results['ram']['free'];
+    $results['ram']['cached'] = 0;
+    $results['ram']['t_used'] = $results['ram']['used'];
+    $results['ram']['t_free'] = $results['ram']['free'];
+
+    $results['ram']['percent'] = round(($results['ram']['used'] * 100) / $results['ram']['total']); 
+    // need to fix the swap info...
+    $pstat = execute_program('swapinfo', '-k');
+    $lines = split("\n", $pstat);
+
+    for ($i = 0, $max = sizeof($lines); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $lines[$i], 6);
+
+      if ($i == 0) {
+        $results['swap']['total'] = 0;
+        $results['swap']['used'] = 0;
+        $results['swap']['free'] = 0;
+      } else {
+        $results['swap']['total'] = $results['swap']['total'] + $ar_buf[1];
+        $results['swap']['used'] = $results['swap']['used'] + $ar_buf[2];
+        $results['swap']['free'] = $results['swap']['free'] + $ar_buf[3];
+      } 
+    } 
+    $results['swap']['percent'] = round(($results['swap']['used'] * 100) / $results['swap']['total']);
+
+    return $results;
+  } 
+
+  function network () {
+    $netstat = execute_program('netstat', '-nbdi | cut -c1-24,42- | grep Link');
+    $lines = split("\n", $netstat);
+    $results = array();
+    for ($i = 0, $max = sizeof($lines); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $lines[$i]);
+      if (!empty($ar_buf[0])) {
+        $results[$ar_buf[0]] = array();
+
+        $results[$ar_buf[0]]['rx_bytes'] = $ar_buf[5];
+        $results[$ar_buf[0]]['rx_packets'] = $ar_buf[3];
+        $results[$ar_buf[0]]['rx_errs'] = $ar_buf[4];
+        $results[$ar_buf[0]]['rx_drop'] = $ar_buf[10];
+
+        $results[$ar_buf[0]]['tx_bytes'] = $ar_buf[8];
+        $results[$ar_buf[0]]['tx_packets'] = $ar_buf[6];
+        $results[$ar_buf[0]]['tx_errs'] = $ar_buf[7];
+        $results[$ar_buf[0]]['tx_drop'] = $ar_buf[10];
+
+        $results[$ar_buf[0]]['errs'] = $ar_buf[4] + $ar_buf[7];
+        $results[$ar_buf[0]]['drop'] = $ar_buf[10];
+      } 
+    } 
+    return $results;
+  } 
+
+  function filesystems () {
+    $df = execute_program('df', '-k');
+    $mounts = split("\n", $df);
+    $fstype = array();
+
+    $s = execute_program('mount');
+    $lines = explode("\n", $s);
+
+    $i = 0;
+    while (list(, $line) = each($lines)) {
+      ereg('(.*) \((.*)\)', $line, $a);
+
+      $m = explode(' ', $a[0]);
+      $fsdev[$m[0]] = $a[2];
+    } 
+
+    for ($i = 1, $j = 0, $max = sizeof($mounts); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $mounts[$i], 6);
+
+      switch ($ar_buf[0]) {
+        case 'automount': // skip the automount entries
+        case 'devfs': // skip the dev filesystem
+        case 'fdesc': // skip the fdesc
+        case 'procfs': // skip the proc filesystem
+        case '<volfs>': // skip the vol filesystem
+          continue 2;
+          break;
+      } 
+      if (hide_mount($ar_buf[5])) {
+        continue;
+      }													
+
+      $results[$j] = array();
+
+      $results[$j]['disk'] = $ar_buf[0];
+      $results[$j]['size'] = $ar_buf[1];
+      $results[$j]['used'] = $ar_buf[2];
+      $results[$j]['free'] = $ar_buf[3];
+      $results[$j]['percent'] = $ar_buf[4];
+      $results[$j]['mount'] = $ar_buf[5];
+      ($fstype[$ar_buf[5]]) ? $results[$j]['fstype'] = $fstype[$ar_buf[5]] : $results[$j]['fstype'] = $fsdev[$ar_buf[0]];
+      $j++;
+    } 
+    return $results;
+  } 
+  
+  function distroicon () {
+    $result = 'Darwin.png';
+    return($result);
+  }
+
+} 
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.FreeBSD.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.FreeBSD.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.FreeBSD.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.FreeBSD.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,108 @@
+<?php 
+
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+
+// 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.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// $Id: class.FreeBSD.inc.php,v 1.17 2006/04/18 16:22:26 bigmichi1 Exp $
+if (!defined('IN_PHPSYSINFO')) {
+    die("No Hacking");
+}
+
+require_once(APP_ROOT . '/class.BSD.common.inc.php');
+
+class sysinfo extends bsd_common {
+  var $cpu_regexp   = "";
+  var $scsi_regexp1 = "";
+  var $scsi_regexp2 = "";
+  var $cpu_regexp2  = "";
+  
+  // Our contstructor
+  // this function is run on the initialization of this class
+  function sysinfo () {
+    $this->bsd_common();
+    $this->cpu_regexp = "CPU: (.*) \((.*)-MHz (.*)\)";
+    $this->scsi_regexp1 = "^(.*): <(.*)> .*SCSI.*device";
+    $this->scsi_regexp2 = "^(da[0-9]): (.*)MB ";
+    $this->cpu_regexp2 = "/(.*) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)/";
+  } 
+
+  function get_sys_ticks () {
+    $s = explode(' ', $this->grab_key('kern.boottime'));
+    $a = ereg_replace('{ ', '', $s[3]);
+    $sys_ticks = time() - $a;
+    return $sys_ticks;
+  } 
+
+  function network () {
+    $netstat = execute_program('netstat', '-nibd | grep Link');
+    $lines = split("\n", $netstat);
+    $results = array();
+    for ($i = 0, $max = sizeof($lines); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $lines[$i]);
+      if (!empty($ar_buf[0])) {
+        $results[$ar_buf[0]] = array();
+
+        if (strlen($ar_buf[3]) < 15) {
+          $results[$ar_buf[0]]['rx_bytes'] = $ar_buf[5];
+          $results[$ar_buf[0]]['rx_packets'] = $ar_buf[3];
+          $results[$ar_buf[0]]['rx_errs'] = $ar_buf[4];
+          $results[$ar_buf[0]]['rx_drop'] = $ar_buf[10];
+
+          $results[$ar_buf[0]]['tx_bytes'] = $ar_buf[8];
+          $results[$ar_buf[0]]['tx_packets'] = $ar_buf[6];
+          $results[$ar_buf[0]]['tx_errs'] = $ar_buf[7];
+          $results[$ar_buf[0]]['tx_drop'] = $ar_buf[10];
+
+          $results[$ar_buf[0]]['errs'] = $ar_buf[4] + $ar_buf[7];
+          $results[$ar_buf[0]]['drop'] = $ar_buf[10];
+        } else {
+          $results[$ar_buf[0]]['rx_bytes'] = $ar_buf[6];
+          $results[$ar_buf[0]]['rx_packets'] = $ar_buf[4];
+          $results[$ar_buf[0]]['rx_errs'] = $ar_buf[5];
+          $results[$ar_buf[0]]['rx_drop'] = $ar_buf[11];
+
+          $results[$ar_buf[0]]['tx_bytes'] = $ar_buf[9];
+          $results[$ar_buf[0]]['tx_packets'] = $ar_buf[7];
+          $results[$ar_buf[0]]['tx_errs'] = $ar_buf[8];
+          $results[$ar_buf[0]]['tx_drop'] = $ar_buf[11];
+
+          $results[$ar_buf[0]]['errs'] = $ar_buf[5] + $ar_buf[8];
+          $results[$ar_buf[0]]['drop'] = $ar_buf[11];
+        } 
+      } 
+    } 
+    return $results;
+  } 
+
+  function distroicon () {
+    $result = 'FreeBSD.png';
+    return($result);
+  }
+  
+  function memory_additional($results) {
+    $pagesize = $this->grab_key("hw.pagesize");
+    $results['ram']['cached'] = $this->grab_key("vm.stats.vm.v_cache_count") * $pagesize / 1024;
+    $results['ram']['cached_percent'] = round( $results['ram']['cached'] * 100 / $results['ram']['total']);
+    $results['ram']['app'] = $this->grab_key("vm.stats.vm.v_active_count") * $pagesize / 1024;
+    $results['ram']['app_percent'] = round( $results['ram']['app'] * 100 / $results['ram']['total']);
+    $results['ram']['buffers'] = $results['ram']['used'] - $results['ram']['app'] - $results['ram']['cached'];
+    $results['ram']['buffers_percent'] = round( $results['ram']['buffers'] * 100 / $results['ram']['total']);
+    return $results;
+  }
+} 
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.HP-UX.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.HP-UX.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.HP-UX.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.HP-UX.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,421 @@
+<?php 
+
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+
+// 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.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// $Id: class.HP-UX.inc.php,v 1.17 2006/02/11 17:31:03 bigmichi1 Exp $
+
+class sysinfo {
+  // get our apache SERVER_NAME or vhost
+  function vhostname () {
+    if (! ($result = getenv('SERVER_NAME'))) {
+      $result = 'N.A.';
+    } 
+    return $result;
+  } 
+  // get our canonical hostname
+  function chostname () {
+    return execute_program('hostname');
+  } 
+  // get the IP address of our canonical hostname
+  function ip_addr () {
+    if (!($result = getenv('SERVER_ADDR'))) {
+      $result = gethostbyname($this->chostname());
+    } 
+    return $result;
+  } 
+
+  function kernel () {
+    return execute_program('uname', '-srvm');
+  } 
+
+  function uptime () {
+    $result = 0;
+    $ar_buf = array();
+
+    $buf = execute_program('uptime');
+    if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $buf, $ar_buf)) {
+      $min = $ar_buf[3];
+      $hours = $ar_buf[2];
+      $days = $ar_buf[1];
+      $result = $days * 86400 + $hours * 3600 + $min * 60;
+    } 
+
+    return $result;
+  } 
+
+  function users () {
+    $who = split('=', execute_program('who', '-q'));
+    $result = $who[1];
+    return $result;
+  } 
+
+  function loadavg ($bar = false) {
+    $ar_buf = array();
+
+    $buf = execute_program('uptime');
+
+    if (preg_match("/average: (.*), (.*), (.*)$/", $buf, $ar_buf)) {
+      $results['avg'] = array($ar_buf[1], $ar_buf[2], $ar_buf[3]);
+    } else {
+      $results['avg'] = array('N.A.', 'N.A.', 'N.A.');
+    } 
+    return $results;
+  } 
+
+  function cpu_info () {
+    $results = array();
+    $ar_buf = array();
+
+    $bufr = rfts( '/proc/cpuinfo' );
+    if( $bufr != "ERROR" ) {
+      $bufe = explode( "\n", $bufr );
+      foreach( $bufe as $buf ) {
+        list($key, $value) = preg_split('/\s+:\s+/', trim($buf), 2); 
+        // All of the tags here are highly architecture dependant.
+        // the only way I could reconstruct them for machines I don't
+        // have is to browse the kernel source.  So if your arch isn't
+        // supported, tell me you want it written in.
+        switch ($key) {
+          case 'model name':
+            $results['model'] = $value;
+            break;
+          case 'cpu MHz':
+            $results['cpuspeed'] = sprintf('%.2f', $value);
+            break;
+          case 'cycle frequency [Hz]': // For Alpha arch - 2.2.x
+            $results['cpuspeed'] = sprintf('%.2f', $value / 1000000);
+            break;
+          case 'clock': // For PPC arch (damn borked POS)
+            $results['cpuspeed'] = sprintf('%.2f', $value);
+            break;
+          case 'cpu': // For PPC arch (damn borked POS)
+            $results['model'] = $value;
+            break;
+          case 'revision': // For PPC arch (damn borked POS)
+            $results['model'] .= ' ( rev: ' . $value . ')';
+            break;
+          case 'cpu model': // For Alpha arch - 2.2.x
+            $results['model'] .= ' (' . $value . ')';
+            break;
+          case 'cache size':
+            $results['cache'] = $value;
+            break;
+          case 'bogomips':
+            $results['bogomips'] += $value;
+            break;
+          case 'BogoMIPS': // For alpha arch - 2.2.x
+            $results['bogomips'] += $value;
+            break;
+          case 'BogoMips': // For sparc arch
+            $results['bogomips'] += $value;
+            break;
+          case 'cpus detected': // For Alpha arch - 2.2.x
+            $results['cpus'] += $value;
+            break;
+          case 'system type': // Alpha arch - 2.2.x
+            $results['model'] .= ', ' . $value . ' ';
+            break;
+          case 'platform string': // Alpha arch - 2.2.x
+            $results['model'] .= ' (' . $value . ')';
+            break;
+          case 'processor':
+            $results['cpus'] += 1;
+            break;
+        } 
+      } 
+      fclose($fd);
+    } 
+
+    $keys = array_keys($results);
+    $keys2be = array('model', 'cpuspeed', 'cache', 'bogomips', 'cpus');
+
+    while ($ar_buf = each($keys2be)) {
+      if (! in_array($ar_buf[1], $keys)) {
+        $results[$ar_buf[1]] = 'N.A.';
+      } 
+    } 
+    return $results;
+  } 
+
+  function pci () {
+    $results = array();
+
+    $bufr = rfts( '/proc/pci' );
+    if( $bufr != "ERROR" ) {
+      $bufe = explode( "\n", $bufr );
+      foreach( $bufe as $buf ) {
+        if (preg_match('/Bus/', $buf)) {
+          $device = true;
+          continue;
+        } 
+
+        if ($device) {
+          list($key, $value) = split(': ', $buf, 2);
+
+          if (!preg_match('/bridge/i', $key) && !preg_match('/USB/i', $key)) {
+            $results[] = preg_replace('/\([^\)]+\)\.$/', '', trim($value));
+          } 
+          $device = false;
+        } 
+      }
+    } 
+    asort($results);
+    return $results;
+  } 
+
+  function ide () {
+    $results = array();
+
+    $bufd = gdc( '/proc/ide' );
+
+    foreach( $bufd as $file ) {
+      if (preg_match('/^hd/', $file)) {
+        $results[$file] = array(); 
+        // Check if device is CD-ROM (CD-ROM capacity shows as 1024 GB)
+	$buf = rfts( "/proc/ide/" . $file . "/media", 1 );
+	if( $buf != "ERROR" ) {
+          $results[$file]['media'] = trim( $buf );
+          if ($results[$file]['media'] == 'disk') {
+            $results[$file]['media'] = 'Hard Disk';
+          } 
+          if ($results[$file]['media'] == 'cdrom') {
+            $results[$file]['media'] = 'CD-ROM';
+          } 
+        } 
+
+	$buf = rfts( "/proc/ide/" . $file . "/model", 1 );
+	if( $buf != "ERROR" ) {
+          $results[$file]['model'] = trim( $buf );
+          if (preg_match('/WDC/', $results[$file]['model'])) {
+            $results[$file]['manufacture'] = 'Western Digital';
+          } elseif (preg_match('/IBM/', $results[$file]['model'])) {
+            $results[$file]['manufacture'] = 'IBM';
+          } elseif (preg_match('/FUJITSU/', $results[$file]['model'])) {
+            $results[$file]['manufacture'] = 'Fujitsu';
+          } else {
+            $results[$file]['manufacture'] = 'Unknown';
+          } 
+        } 
+
+	$buf = rfts( "/proc/ide/" . $file . "/capacity", 1 );
+	if( $buf != "ERROR" ) {
+          $results[$file]['capacity'] = trim( $buf );
+          if ($results[$file]['media'] == 'CD-ROM') {
+            unset($results[$file]['capacity']);
+          } 
+        } 
+      } 
+    } 
+    asort($results);
+    return $results;
+  } 
+
+  function scsi () {
+    $results = array();
+    $dev_vendor = '';
+    $dev_model = '';
+    $dev_rev = '';
+    $dev_type = '';
+    $s = 1;
+
+    $bufr = rfts( '/proc/scsi/scsi' );
+    if( $bufr != "ERROR" ) {
+      $bufe = explode( "\n", $bufr );
+      foreach( $bufe as $buf ) {
+        if (preg_match('/Vendor/', $buf)) {
+          preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $dev);
+          list($key, $value) = split(': ', $buf, 2);
+          $dev_str = $value;
+          $get_type = 1;
+          continue;
+        } 
+
+        if ($get_type) {
+          preg_match('/Type:\s+(\S+)/i', $buf, $dev_type);
+          $results[$s]['model'] = "$dev[1] $dev[2] ($dev_type[1])";
+          $results[$s]['media'] = "Hard Disk";
+          $s++;
+          $get_type = 0;
+        } 
+      }
+    } 
+    asort($results);
+    return $results;
+  } 
+
+  function usb () {
+    $results = array();
+    $devstring = 0;
+    $devnum = -1;
+
+    $bufr = rfts( '/proc/bus/usb/devices' );
+    if( $bufr != "ERROR" ) {
+      $bufe = explode( "\n", $bufr );
+      foreach( $bufe as $buf ) {
+        if (preg_match('/^T/', $buf)) {
+          $devnum += 1;
+        } 
+        if (preg_match('/^S/', $buf)) {
+          $devstring = 1;
+        } 
+
+        if ($devstring) {
+          list($key, $value) = split(': ', $buf, 2);
+          list($key, $value2) = split('=', $value, 2);
+          $results[$devnum] .= " " . trim($value2);
+          $devstring = 0;
+        } 
+      }
+    } 
+    return $results;
+  } 
+
+  function sbus () {
+    $results = array();
+    $_results[0] = "";
+    // TODO. Nothing here yet. Move along.
+    $results = $_results;
+    return $results;
+  }
+
+  function network () {
+    $netstat = execute_program('netstat', '-ni | tail -n +2');
+    $lines = split("\n", $netstat);
+    $results = array();
+    for ($i = 0, $max = sizeof($lines); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $lines[$i]);
+      if (!empty($ar_buf[0]) && !empty($ar_buf[3])) {
+        $results[$ar_buf[0]] = array();
+
+        $results[$ar_buf[0]]['rx_bytes'] = $ar_buf[4];
+        $results[$ar_buf[0]]['rx_packets'] = $ar_buf[4];
+        $results[$ar_buf[0]]['rx_errs'] = $ar_buf[5];
+        $results[$ar_buf[0]]['rx_drop'] = $ar_buf[8];
+
+        $results[$ar_buf[0]]['tx_bytes'] = $ar_buf[6];
+        $results[$ar_buf[0]]['tx_packets'] = $ar_buf[6];
+        $results[$ar_buf[0]]['tx_errs'] = $ar_buf[7];
+        $results[$ar_buf[0]]['tx_drop'] = $ar_buf[8];
+
+        $results[$ar_buf[0]]['errs'] = $ar_buf[5] + $ar_buf[7];
+        $results[$ar_buf[0]]['drop'] = $ar_buf[8];
+      } 
+    } 
+    return $results;
+  } 
+  function memory () {
+    $results['ram'] = array();
+    $results['swap'] = array();
+    $results['devswap'] = array();
+
+    $bufr = rfts( '/proc/meminfo' );
+    if( $bufr != "ERROR" ) {
+      $bufe = explode( "\n", $bufr );
+      foreach( $bufe as $buf ) {
+        if (preg_match('/Mem:\s+(.*)$/', $buf, $ar_buf)) {
+          $ar_buf = preg_split('/\s+/', $ar_buf[1], 6);
+
+          $results['ram']['total'] = $ar_buf[0] / 1024;
+          $results['ram']['used'] = $ar_buf[1] / 1024;
+          $results['ram']['free'] = $ar_buf[2] / 1024;
+          $results['ram']['shared'] = $ar_buf[3] / 1024;
+          $results['ram']['buffers'] = $ar_buf[4] / 1024;
+          $results['ram']['cached'] = $ar_buf[5] / 1024; 
+          // I don't like this since buffers and cache really aren't
+          // 'used' per say, but I get too many emails about it.
+          $results['ram']['t_used'] = $results['ram']['used'];
+          $results['ram']['t_free'] = $results['ram']['total'] - $results['ram']['t_used'];
+          $results['ram']['percent'] = round(($results['ram']['t_used'] * 100) / $results['ram']['total']);
+        } 
+
+        if (preg_match('/Swap:\s+(.*)$/', $buf, $ar_buf)) {
+          $ar_buf = preg_split('/\s+/', $ar_buf[1], 3);
+
+          $results['swap']['total'] = $ar_buf[0] / 1024;
+          $results['swap']['used'] = $ar_buf[1] / 1024;
+          $results['swap']['free'] = $ar_buf[2] / 1024;
+          $results['swap']['percent'] = round(($ar_buf[1] * 100) / $ar_buf[0]); 
+          // Get info on individual swap files
+	  $swaps = rfts( '/proc/swaps' );
+	  if( $swaps != "ERROR" ) {
+            $swapdevs = split("\n", $swaps);
+
+            for ($i = 1, $max = (sizeof($swapdevs) - 1); $i < $max; $i++) {
+              $ar_buf = preg_split('/\s+/', $swapdevs[$i], 6);
+              $results['devswap'][$i - 1] = array();
+              $results['devswap'][$i - 1]['dev'] = $ar_buf[0];
+              $results['devswap'][$i - 1]['total'] = $ar_buf[2];
+              $results['devswap'][$i - 1]['used'] = $ar_buf[3];
+              $results['devswap'][$i - 1]['free'] = ($results['devswap'][$i - 1]['total'] - $results['devswap'][$i - 1]['used']);
+              $results['devswap'][$i - 1]['percent'] = round(($ar_buf[3] * 100) / $ar_buf[2]);
+            } 
+            break;
+	  }
+        } 
+      } 
+    } 
+    return $results;
+  } 
+
+  function filesystems () {
+    $df = execute_program('df', '-kP');
+    $mounts = split("\n", $df);
+    $fstype = array();
+
+    $s = execute_program('mount', '-v');
+    $lines = explode("\n", $s);
+
+    $i = 0;
+    while (list(, $line) = each($lines)) {
+      $a = split(' ', $line);
+      $fsdev[$a[0]] = $a[4];
+    } 
+
+    for ($i = 1, $j = 0, $max = sizeof($mounts); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $mounts[$i], 6);
+
+      if (hide_mount($ar_buf[5])) {
+        continue;
+      }
+
+      $results[$j] = array();
+
+      $results[$j]['disk'] = $ar_buf[0];
+      $results[$j]['size'] = $ar_buf[1];
+      $results[$j]['used'] = $ar_buf[2];
+      $results[$j]['free'] = $ar_buf[3];
+      $results[$j]['percent'] = $ar_buf[4];
+      $results[$j]['mount'] = $ar_buf[5];
+      ($fstype[$ar_buf[5]]) ? $results[$j]['fstype'] = $fstype[$ar_buf[5]] : $results[$j]['fstype'] = $fsdev[$ar_buf[0]];
+      $j++;
+    } 
+    return $results;
+  } 
+  
+  function distro () {
+    $result = 'HP-UX';  	
+    return($result);
+  }
+
+  function distroicon () {
+    $result = 'unknown.png';
+    return($result);
+  }
+} 
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.Linux.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.Linux.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.Linux.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.Linux.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,530 @@
+<?php 
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+// 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.
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// $Id: class.Linux.inc.php,v 1.73 2006/04/22 14:35:57 bigmichi1 Exp $
+
+if (!defined('IN_PHPSYSINFO')) {
+    die("No Hacking");
+}
+
+require_once(APP_ROOT . '/class.BSD.common.inc.php');
+
+class sysinfo {
+  var $inifile = "distros.ini";
+  var $icon = "unknown.png";
+  var $distro = "unknown";
+
+    var $parser;
+  // get the distro name and icon when create the sysinfo object
+  function sysinfo() {
+  
+    $this->parser = new Parser();
+    $this->parser->df_param = 'P';
+  
+   $list = parse_ini_file(APP_ROOT . "/" . $this->inifile, true);
+   if (!$list) {
+    return;
+   }
+   foreach ($list as $section => $distribution) {
+    if (!isset($distribution["Files"])) {
+     continue;
+    } else {
+     foreach (explode(";", $distribution["Files"]) as $filename) {
+      if (file_exists($filename)) {
+       $buf = rfts( $filename );
+       $this->icon = isset($distribution["Image"]) ? $distribution["Image"] : $this->icon;
+       $this->distro = isset($distribution["Name"]) ? $distribution["Name"] . " " . trim($buf) : trim($buf);
+	   $this->distroname = $section;
+       break 2;
+      }
+     }
+    }
+   }
+  }
+
+  // get our apache SERVER_NAME or vhost
+  function vhostname () {
+    if (! ($result = getenv('SERVER_NAME'))) {
+      $result = 'N.A.';
+    } 
+    return $result;
+  } 
+  // get our canonical hostname
+  function chostname () {
+    $result = rfts( '/proc/sys/kernel/hostname', 1 );
+    if ( $result == "ERROR" ) {
+      $result = "N.A.";
+    } else {
+      $result = gethostbyaddr( gethostbyname( trim( $result ) ) );
+    } 
+    return $result;
+  } 
+  // get the IP address of our canonical hostname
+  function ip_addr () {
+    if (!($result = getenv('SERVER_ADDR'))) {
+      $result = gethostbyname($this->chostname());
+    } 
+    return $result;
+  } 
+
+  function kernel () {
+    $buf = rfts( '/proc/version', 1 );
+    if ( $buf == "ERROR" ) {
+      $result = "N.A.";
+    } else {
+      if (preg_match('/version (.*?) /', $buf, $ar_buf)) {
+        $result = $ar_buf[1];
+
+        if (preg_match('/SMP/', $buf)) {
+          $result .= ' (SMP)';
+        } 
+      } 
+    } 
+    return $result;
+  } 
+  
+  function uptime () {
+    $buf = rfts( '/proc/uptime', 1 );
+    $ar_buf = split( ' ', $buf );
+    $result = trim( $ar_buf[0] );
+
+    return $result;
+  } 
+
+  function users () {
+    $who = split('=', execute_program('who', '-q'));
+    $result = $who[1];
+    return $result;
+  } 
+
+  function loadavg ($bar = false) {
+    $buf = rfts( '/proc/loadavg' );
+    if( $buf == "ERROR" ) {
+      $results['avg'] = array('N.A.', 'N.A.', 'N.A.');
+    } else {
+      $results['avg'] = preg_split("/\s/", $buf, 4);
+      unset($results['avg'][3]);	// don't need the extra values, only first three
+    } 
+    if ($bar) {
+      $buf = rfts( '/proc/stat', 1 );
+      if( $buf != "ERROR" ) {
+	sscanf($buf, "%*s %Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
+	// Find out the CPU load
+	// user + sys = load 
+	// total = total
+	$load = $ab + $ac + $ad;	// cpu.user + cpu.sys
+	$total = $ab + $ac + $ad + $ae;	// cpu.total
+
+	// we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
+	sleep(1);
+	$buf = rfts( '/proc/stat', 1 );
+	sscanf($buf, "%*s %Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
+	$load2 = $ab + $ac + $ad;
+	$total2 = $ab + $ac + $ad + $ae;
+	$results['cpupercent'] = ($total2 != $total)?((100*($load2 - $load)) / ($total2 - $total)):0;
+      }
+    }
+    return $results;
+  } 
+
+  function cpu_info () {
+    $bufr = rfts( '/proc/cpuinfo' );
+
+    if ( $bufr != "ERROR" ) {
+      $bufe = explode("\n", $bufr);
+
+      $results = array('cpus' => 0, 'bogomips' => 0);
+      $ar_buf = array();
+      
+      foreach( $bufe as $buf ) {
+       if(trim($buf) != "") {
+        list($key, $value) = preg_split('/\s+:\s+/', trim($buf), 2); 
+        // All of the tags here are highly architecture dependant.
+        // the only way I could reconstruct them for machines I don't
+        // have is to browse the kernel source.  So if your arch isn't
+        // supported, tell me you want it written in.
+        switch ($key) {
+          case 'model name':
+            $results['model'] = $value;
+            break;
+          case 'cpu MHz':
+            $results['cpuspeed'] = sprintf('%.2f', $value);
+            break;
+          case 'cycle frequency [Hz]': // For Alpha arch - 2.2.x
+            $results['cpuspeed'] = sprintf('%.2f', $value / 1000000);
+            break;
+          case 'clock': // For PPC arch (damn borked POS)
+            $results['cpuspeed'] = sprintf('%.2f', $value);
+            break;
+          case 'cpu': // For PPC arch (damn borked POS)
+            $results['model'] = $value;
+            break;
+          case 'L2 cache': // More for PPC
+            $results['cache'] = $value;
+            break;
+          case 'revision': // For PPC arch (damn borked POS)
+            $results['model'] .= ' ( rev: ' . $value . ')';
+            break;
+          case 'cpu model': // For Alpha arch - 2.2.x
+            $results['model'] .= ' (' . $value . ')';
+            break;
+          case 'cache size':
+            $results['cache'] = $value;
+            break;
+          case 'bogomips':
+            $results['bogomips'] += $value;
+            break;
+          case 'BogoMIPS': // For alpha arch - 2.2.x
+            $results['bogomips'] += $value;
+            break;
+          case 'BogoMips': // For sparc arch
+            $results['bogomips'] += $value;
+            break;
+          case 'cpus detected': // For Alpha arch - 2.2.x
+            $results['cpus'] += $value;
+            break;
+          case 'system type': // Alpha arch - 2.2.x
+            $results['model'] .= ', ' . $value . ' ';
+            break;
+          case 'platform string': // Alpha arch - 2.2.x
+            $results['model'] .= ' (' . $value . ')';
+            break;
+          case 'processor':
+            $results['cpus'] += 1;
+            break;
+          case 'Cpu0ClkTck': // Linux sparc64
+            $results['cpuspeed'] = sprintf('%.2f', hexdec($value) / 1000000);
+            break;
+          case 'Cpu0Bogo': // Linux sparc64 & sparc32
+            $results['bogomips'] = $value;
+            break;
+          case 'ncpus probed': // Linux sparc64 & sparc32
+            $results['cpus'] = $value;
+            break;
+        } 
+       }
+      } 
+    } 
+
+    // sparc64 specific code follows
+    // This adds the ability to display the cache that a CPU has
+    // Originally made by Sven Blumenstein <bazik at gentoo.org> in 2004
+    // Modified by Tom Weustink <freshy98 at gmx.net> in 2004
+    $sparclist = array('SUNW,UltraSPARC at 0,0', 'SUNW,UltraSPARC-II at 0,0', 'SUNW,UltraSPARC at 1c,0', 'SUNW,UltraSPARC-IIi at 1c,0', 'SUNW,UltraSPARC-II at 1c,0');
+    foreach ($sparclist as $name) {
+      $buf = rfts( '/proc/openprom/' . $name . '/ecache-size',1 , 32, false );
+      if( $buf != "ERROR" ) {
+        $results['cache'] = base_convert($buf, 16, 10)/1024 . ' KB';
+      }
+    }
+    // sparc64 specific code ends
+
+    // XScale detection code
+    if ( $results['cpus'] == 0 ) {
+      foreach( $bufe as $buf ) {
+       if($buf != "\n") {
+         list($key, $value) = preg_split('/\s+:\s+/', trim($buf), 2);
+	 switch($key) {
+	   case 'Processor':
+	    $results['cpus'] += 1;
+	    $results['model'] = $value;
+	    break;
+          case 'BogoMIPS': //BogoMIPS are not BogoMIPS on this CPU, it's the speed, no BogoMIPS available
+            $results['cpuspeed'] = $value;
+            break;
+          case 'I size':
+	    $results['cache'] = $value;
+	    break;
+	  case 'D size':
+	    $results['cache'] += $value;
+	    break;
+	 }
+       }
+      }
+      $results['cache'] = $results['cache'] / 1024 . " KB";
+    }
+
+    $keys = array_keys($results);
+    $keys2be = array('model', 'cpuspeed', 'cache', 'bogomips', 'cpus');
+
+    while ($ar_buf = each($keys2be)) {
+      if (! in_array($ar_buf[1], $keys)) {
+        $results[$ar_buf[1]] = 'N.A.';
+      } 
+    } 
+    return $results;
+  } 
+
+  function pci () {
+    $results = array();
+
+    if( !$results = $this->parser->parse_lspci() ) {
+      $bufr = rfts( '/proc/pci' );
+      foreach( $bufr as $buf ) {
+        if (preg_match('/Bus/', $buf)) {
+          $device = true;
+          continue;
+        } 
+
+        if ($device) {
+          list($key, $value) = split(': ', $buf, 2);
+
+          if (!preg_match('/bridge/i', $key) && !preg_match('/USB/i', $key)) {
+            $results[] = preg_replace('/\([^\)]+\)\.$/', '', trim($value));
+          } 
+          $device = false;
+        } 
+      } 
+    } 
+    asort($results);
+    return $results;
+  } 
+
+  function ide () {
+    $results = array();
+    $bufd = gdc( '/proc/ide' );
+
+    foreach( $bufd as $file ) {
+      if (preg_match('/^hd/', $file)) {
+        $results[$file] = array(); 
+	$buf = rfts("/proc/ide/" . $file . "/media", 1 );
+        if ( $buf != "ERROR" ) {
+          $results[$file]['media'] = trim($buf);
+          if ($results[$file]['media'] == 'disk') {
+            $results[$file]['media'] = 'Hard Disk';
+	    $buf = rfts( "/proc/ide/" . $file . "/capacity", 1, 4096, false);
+	    if( $buf == "ERROR" ) {
+		$buf = rfts( "/sys/block/" . $file . "/size", 1, 4096, false);
+	    }
+	    if ( $buf != "ERROR" ) {
+    	        $results[$file]['capacity'] = trim( $buf );
+    	    } 
+          } elseif ($results[$file]['media'] == 'cdrom') {
+            $results[$file]['media'] = 'CD-ROM';
+	    unset($results[$file]['capacity']);
+          } 
+        } 
+
+	$buf = rfts( "/proc/ide/" . $file . "/model", 1 );
+        if ( $buf != "ERROR" ) {
+          $results[$file]['model'] = trim( $buf );
+          if (preg_match('/WDC/', $results[$file]['model'])) {
+            $results[$file]['manufacture'] = 'Western Digital';
+          } elseif (preg_match('/IBM/', $results[$file]['model'])) {
+            $results[$file]['manufacture'] = 'IBM';
+          } elseif (preg_match('/FUJITSU/', $results[$file]['model'])) {
+            $results[$file]['manufacture'] = 'Fujitsu';
+          } else {
+            $results[$file]['manufacture'] = 'Unknown';
+          } 
+        } 
+	
+      } 
+    } 
+
+    asort($results);
+    return $results;
+  } 
+
+  function scsi () {
+    $results = array();
+    $dev_vendor = '';
+    $dev_model = '';
+    $dev_rev = '';
+    $dev_type = '';
+    $s = 1;
+    $get_type = 0;
+
+    $bufr = execute_program('lsscsi', '-c', false);
+    if( is_null( $bufr )) {
+	$bufr = rfts( '/proc/scsi/scsi' );
+    }
+    if ( $bufr != "ERROR" ) {
+      $bufe = explode("\n", $bufr);
+      foreach( $bufe as $buf ) {
+        if (preg_match('/Vendor/', $buf)) {
+          preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $dev);
+          list($key, $value) = split(': ', $buf, 2);
+          $dev_str = $value;
+          $get_type = true;
+          continue;
+        } 
+
+        if ($get_type) {
+          preg_match('/Type:\s+(\S+)/i', $buf, $dev_type);
+          $results[$s]['model'] = "$dev[1] $dev[2] ($dev_type[1])";
+          $results[$s]['media'] = "Hard Disk";
+          $s++;
+          $get_type = false;
+        } 
+      } 
+    } 
+    asort($results);
+    return $results;
+  } 
+
+  function usb () {
+    $results = array();
+    $devnum = -1;
+
+    $bufr = execute_program('lsusb', '', false);
+    if( is_null( $bufr )) {
+	$bufr = rfts( '/proc/bus/usb/devices' );
+        if ( $bufr != "ERROR" ) {
+    	    $bufe = explode("\n", $bufr);
+	    foreach( $bufe as $buf ) {
+        	if (preg_match('/^T/', $buf)) {
+            	    $devnum += 1;
+    		    $results[$devnum] = "";
+        	} elseif (preg_match('/^S:/', $buf)) {
+            	    list($key, $value) = split(': ', $buf, 2);
+            	    list($key, $value2) = split('=', $value, 2);
+    		    if (trim($key) != "SerialNumber") {
+            		$results[$devnum] .= " " . trim($value2);
+            		$devstring = 0;
+    		    }
+        	} 
+            }
+        } 
+    } else {
+	$bufe = explode( "\n", $bufr );
+	foreach( $bufe as $buf ) {
+	    $device = preg_split("/ /", $buf, 7);
+	    if( isset( $device[6] ) && trim( $device[6] ) != "" ) {
+		$results[$devnum++] = trim( $device[6] );
+	    }
+	}
+    }
+    return $results;
+  } 
+
+  function sbus () {
+    $results = array();
+    $_results[0] = ""; 
+    // TODO. Nothing here yet. Move along.
+    $results = $_results;
+    return $results;
+  } 
+
+  function network () {
+    $results = array();
+
+    $bufr = rfts( '/proc/net/dev' );
+    if ( $bufr != "ERROR" ) {
+      $bufe = explode("\n", $bufr);
+      foreach( $bufe as $buf ) {
+        if (preg_match('/:/', $buf)) {
+          list($dev_name, $stats_list) = preg_split('/:/', $buf, 2);
+          $stats = preg_split('/\s+/', trim($stats_list));
+          $results[$dev_name] = array();
+
+          $results[$dev_name]['rx_bytes'] = $stats[0];
+          $results[$dev_name]['rx_packets'] = $stats[1];
+          $results[$dev_name]['rx_errs'] = $stats[2];
+          $results[$dev_name]['rx_drop'] = $stats[3];
+
+          $results[$dev_name]['tx_bytes'] = $stats[8];
+          $results[$dev_name]['tx_packets'] = $stats[9];
+          $results[$dev_name]['tx_errs'] = $stats[10];
+          $results[$dev_name]['tx_drop'] = $stats[11];
+
+          $results[$dev_name]['errs'] = $stats[2] + $stats[10];
+          $results[$dev_name]['drop'] = $stats[3] + $stats[11];
+        } 
+      }
+    }
+    return $results;
+  } 
+
+	function memory () {
+		$results['ram'] = array();
+		$results['swap'] = array();
+		$results['devswap'] = array();
+
+		$bufr = rfts( '/proc/meminfo' );
+		if ( $bufr != "ERROR" ) {
+			$bufe = explode("\n", $bufr);
+			foreach( $bufe as $buf ) {
+				if (preg_match('/^MemTotal:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
+					$results['ram']['total'] = $ar_buf[1];
+				} else if (preg_match('/^MemFree:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
+					$results['ram']['t_free'] = $ar_buf[1];
+				} else if (preg_match('/^Cached:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
+					$results['ram']['cached'] = $ar_buf[1];
+				} else if (preg_match('/^Buffers:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
+					$results['ram']['buffers'] = $ar_buf[1];
+				} else if (preg_match('/^SwapTotal:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
+					$results['swap']['total'] = $ar_buf[1];
+				} else if (preg_match('/^SwapFree:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
+					$results['swap']['free'] = $ar_buf[1];
+				} 
+			} 
+
+			$results['ram']['t_used'] = $results['ram']['total'] - $results['ram']['t_free'];
+			$results['ram']['percent'] = round(($results['ram']['t_used'] * 100) / $results['ram']['total']);
+			$results['swap']['used'] = $results['swap']['total'] - $results['swap']['free'];
+
+			// If no swap, avoid divide by 0
+			//
+			if (trim($results['swap']['total'])) {
+				$results['swap']['percent'] = round(($results['swap']['used'] * 100) / $results['swap']['total']);
+			} else {
+				$results['swap']['percent'] = 0;
+			}
+      
+			// values for splitting memory usage
+			if (isset($results['ram']['cached']) && isset($results['ram']['buffers'])) {
+				$results['ram']['app'] = $results['ram']['t_used'] - $results['ram']['cached'] - $results['ram']['buffers'];
+				$results['ram']['app_percent'] = round(($results['ram']['app'] * 100) / $results['ram']['total']);
+				$results['ram']['buffers_percent'] = round(($results['ram']['buffers'] * 100) / $results['ram']['total']);
+				$results['ram']['cached_percent'] = round(($results['ram']['cached'] * 100) / $results['ram']['total']);
+			}
+
+			$bufr = rfts( '/proc/swaps' );
+			if ( $bufr != "ERROR" ) {
+				$swaps = explode("\n", $bufr);
+				for ($i = 1; $i < (sizeof($swaps)); $i++) {
+					if( trim( $swaps[$i] ) != "" ) {
+						$ar_buf = preg_split('/\s+/', $swaps[$i], 6);
+						$results['devswap'][$i - 1] = array();
+						$results['devswap'][$i - 1]['dev'] = $ar_buf[0];
+						$results['devswap'][$i - 1]['total'] = $ar_buf[2];
+						$results['devswap'][$i - 1]['used'] = $ar_buf[3];
+						$results['devswap'][$i - 1]['free'] = ($results['devswap'][$i - 1]['total'] - $results['devswap'][$i - 1]['used']);
+						$results['devswap'][$i - 1]['percent'] = round(($ar_buf[3] * 100) / $ar_buf[2]);
+					}
+				}
+			}
+		}
+		return $results;
+	} 
+
+  function filesystems () {
+    return $this->parser->parse_filesystems();
+  } 
+
+  function distro () {
+   return $this->distro;
+  }
+  function distroname () {
+   return $this->distroname;
+  }
+
+  function distroicon () {   
+   return $this->icon;
+  }
+
+} 
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.NetBSD.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.NetBSD.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.NetBSD.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.NetBSD.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,111 @@
+<?php 
+
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+
+// 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.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// $Id: class.NetBSD.inc.php,v 1.18 2006/04/18 16:57:32 bigmichi1 Exp $
+if (!defined('IN_PHPSYSINFO')) {
+    die("No Hacking");
+}
+
+require_once(APP_ROOT . '/class.BSD.common.inc.php');
+
+class sysinfo extends bsd_common {
+  var $cpu_regexp;
+  var $scsi_regexp; 
+  // Our contstructor
+  // this function is run on the initialization of this class
+  function sysinfo () {
+    $this->bsd_common();
+    
+    $this->cpu_regexp = "^cpu(.*)\, (.*) MHz";
+    $this->scsi_regexp1 = "^(.*) at scsibus.*: <(.*)> .*";
+    $this->scsi_regexp2 = "^(da[0-9]): (.*)MB ";
+    $this->cpu_regexp2 = "/user = (.*), nice = (.*), sys = (.*), intr = (.*), idle = (.*)/";
+    $this->pci_regexp1 = '/(.*) at pci[0-9] dev [0-9]* function [0-9]*: (.*)$/';
+    $this->pci_regexp2 = '/"(.*)" (.*).* at [.0-9]+ irq/';
+  } 
+
+  function get_sys_ticks () {
+    $a = $this->grab_key('kern.boottime');
+    $sys_ticks = time() - $a;
+    return $sys_ticks;
+  } 
+
+  function network () {
+    $netstat_b = execute_program('netstat', '-nbdi | cut -c1-25,44- | grep "^[a-z]*[0-9][ \t].*Link"');
+    $netstat_n = execute_program('netstat', '-ndi | cut -c1-25,44- | grep "^[a-z]*[0-9][ \t].*Link"');
+    $lines_b = split("\n", $netstat_b);
+    $lines_n = split("\n", $netstat_n);
+    $results = array();
+    for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) {
+      $ar_buf_b = preg_split("/\s+/", $lines_b[$i]);
+      $ar_buf_n = preg_split("/\s+/", $lines_n[$i]);
+      if (!empty($ar_buf_b[0]) && !empty($ar_buf_n[3])) {
+        $results[$ar_buf_b[0]] = array();
+
+        $results[$ar_buf_b[0]]['rx_bytes'] = $ar_buf_b[3];
+        $results[$ar_buf_b[0]]['rx_packets'] = $ar_buf_n[3];
+        $results[$ar_buf_b[0]]['rx_errs'] = $ar_buf_n[4];
+        $results[$ar_buf_b[0]]['rx_drop'] = $ar_buf_n[8];
+
+        $results[$ar_buf_b[0]]['tx_bytes'] = $ar_buf_b[4];
+        $results[$ar_buf_b[0]]['tx_packets'] = $ar_buf_n[5];
+        $results[$ar_buf_b[0]]['tx_errs'] = $ar_buf_n[6];
+        $results[$ar_buf_b[0]]['tx_drop'] = $ar_buf_n[8];
+
+        $results[$ar_buf_b[0]]['errs'] = $ar_buf_n[4] + $ar_buf_n[6];
+        $results[$ar_buf_b[0]]['drop'] = $ar_buf_n[8];
+      } 
+    } 
+    return $results;
+  } 
+
+  // get the ide device information out of dmesg
+  function ide () {
+    $results = array();
+
+    $s = 0;
+    for ($i = 0, $max = count($this->read_dmesg()); $i < $max; $i++) {
+      $buf = $this->dmesg[$i];
+      if (preg_match('/^(.*) at (pciide|wdc|atabus|atapibus)[0-9] (.*): <(.*)>/', $buf, $ar_buf)) {
+        $s = $ar_buf[1];
+        $results[$s]['model'] = $ar_buf[4];
+        $results[$s]['media'] = 'Hard Disk'; 
+        // now loop again and find the capacity
+        for ($j = 0, $max1 = count($this->read_dmesg()); $j < $max1; $j++) {
+          $buf_n = $this->dmesg[$j];
+          if (preg_match("/^($s): (.*), (.*), (.*)MB, .*$/", $buf_n, $ar_buf_n)) {
+            $results[$s]['capacity'] = $ar_buf_n[4] * 2048 * 1.049;
+          } elseif (preg_match("/^($s): (.*) MB, (.*), (.*), .*$/", $buf_n, $ar_buf_n)) {
+	    $results[$s]['capacity'] = $ar_buf_n[2] * 2048;
+	  }
+        } 
+      } 
+    } 
+    asort($results);
+    return $results;
+  } 
+
+  function distroicon () {
+    $result = 'NetBSD.png';
+    return($result);
+  }
+  
+} 
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.OpenBSD.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.OpenBSD.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.OpenBSD.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.OpenBSD.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,110 @@
+<?php 
+
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+
+// 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.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// $Id: class.OpenBSD.inc.php,v 1.21 2006/04/18 17:46:15 bigmichi1 Exp $
+if (!defined('IN_PHPSYSINFO')) {
+    die("No Hacking");
+}
+
+require_once(APP_ROOT . '/class.BSD.common.inc.php');
+
+class sysinfo extends bsd_common {
+  var $cpu_regexp   = "";
+  var $scsi_regexp1 = "";
+  var $scsi_regexp2 = "";
+  var $cpu_regexp2  = "";
+  
+  // Our contstructor
+  // this function is run on the initialization of this class
+  function sysinfo () {
+    $this->bsd_common();
+    $this->cpu_regexp = "^cpu(.*) (.*) MHz";
+    $this->scsi_regexp1 = "^(.*) at scsibus.*: <(.*)> .*";
+    $this->scsi_regexp2 = "^(da[0-9]): (.*)MB ";
+    $this->cpu_regexp2 = "/(.*),(.*),(.*),(.*),(.*)/";
+    $this->pci_regexp1 = '/(.*) at pci[0-9] .* "(.*)"/';
+    $this->pci_regexp2 = '/"(.*)" (.*).* at [.0-9]+ irq/';
+  } 
+
+  function get_sys_ticks () {
+    $a = $this->grab_key('kern.boottime');
+    $sys_ticks = time() - $a;
+    return $sys_ticks;
+  } 
+
+  function network () {
+    $netstat_b = execute_program('netstat', '-nbdi | cut -c1-25,44- | grep Link | grep -v \'* \'');
+    $netstat_n = execute_program('netstat', '-ndi | cut -c1-25,44- | grep Link | grep -v \'* \'');
+    $lines_b = split("\n", $netstat_b);
+    $lines_n = split("\n", $netstat_n);
+    $results = array();
+    for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) {
+      $ar_buf_b = preg_split("/\s+/", $lines_b[$i]);
+      $ar_buf_n = preg_split("/\s+/", $lines_n[$i]);
+      if (!empty($ar_buf_b[0]) && !empty($ar_buf_n[3])) {
+        $results[$ar_buf_b[0]] = array();
+
+        $results[$ar_buf_b[0]]['rx_bytes'] = $ar_buf_b[3];
+        $results[$ar_buf_b[0]]['rx_packets'] = $ar_buf_n[3];
+        $results[$ar_buf_b[0]]['rx_errs'] = $ar_buf_n[4];
+        $results[$ar_buf_b[0]]['rx_drop'] = $ar_buf_n[8];
+
+        $results[$ar_buf_b[0]]['tx_bytes'] = $ar_buf_b[4];
+        $results[$ar_buf_b[0]]['tx_packets'] = $ar_buf_n[5];
+        $results[$ar_buf_b[0]]['tx_errs'] = $ar_buf_n[6];
+        $results[$ar_buf_b[0]]['tx_drop'] = $ar_buf_n[8];
+
+        $results[$ar_buf_b[0]]['errs'] = $ar_buf_n[4] + $ar_buf_n[6];
+        $results[$ar_buf_b[0]]['drop'] = $ar_buf_n[8];
+      } 
+    } 
+    return $results;
+  } 
+  // get the ide device information out of dmesg
+  function ide () {
+    $results = array();
+
+    $s = 0;
+    for ($i = 0, $max = count($this->read_dmesg()); $i < $max; $i++) {
+      $buf = $this->dmesg[$i];
+      if (preg_match('/^(.*) at pciide[0-9] (.*): <(.*)>/', $buf, $ar_buf)) {
+        $s = $ar_buf[1];
+        $results[$s]['model'] = $ar_buf[3];
+        $results[$s]['media'] = 'Hard Disk'; 
+        // now loop again and find the capacity
+        for ($j = 0, $max1 = count($this->read_dmesg()); $j < $max1; $j++) {
+          $buf_n = $this->dmesg[$j];
+          if (preg_match("/^($s): (.*), (.*), (.*)MB, .*$/", $buf_n, $ar_buf_n)) {
+            $results[$s]['capacity'] = $ar_buf_n[4] * 2048 * 1.049;;
+          } 
+        } 
+      } 
+    } 
+    asort($results);
+    return $results;
+  } 
+
+  function distroicon () {
+    $result = 'OpenBSD.png';
+    return($result);
+  }
+  
+} 
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.SunOS.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.SunOS.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.SunOS.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.SunOS.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,238 @@
+<?php 
+
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+
+// 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.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// $Id: class.SunOS.inc.php,v 1.22 2006/02/11 17:55:25 bigmichi1 Exp $
+
+$error->addError("WARN", "The SunOS version of phpSysInfo is work in progress, some things currently don't work");
+
+class sysinfo {
+  // Extract kernel values via kstat() interface
+  function kstat ($key) {
+    $m = execute_program('kstat', "-p d $key");
+    list($key, $value) = split("\t", trim($m), 2);
+    return $value;
+  } 
+
+  function vhostname () {
+    if (! ($result = getenv('SERVER_NAME'))) {
+      $result = 'N.A.';
+    } 
+    return $result;
+  } 
+  // get our canonical hostname
+  function chostname () {
+    if ($result = execute_program('uname', '-n')) {
+      $result = gethostbyaddr(gethostbyname($result));
+    } else {
+      $result = 'N.A.';
+    } 
+    return $result;
+  } 
+  // get the IP address of our canonical hostname
+  function ip_addr () {
+    if (!($result = getenv('SERVER_ADDR'))) {
+      $result = gethostbyname($this->chostname());
+    } 
+    return $result;
+  } 
+
+  function kernel () {
+    $os = execute_program('uname', '-s');
+    $version = execute_program('uname', '-r');
+    return $os . ' ' . $version;
+  } 
+
+  function uptime () {
+    $result = time() - $this->kstat('unix:0:system_misc:boot_time');
+
+    return $result;
+  } 
+
+  function users () {
+    $who = split('=', execute_program('who', '-q'));
+    $result = $who[1];
+    return $result;
+  } 
+
+  function loadavg ($bar = false) {
+    $load1 = $this->kstat('unix:0:system_misc:avenrun_1min');
+    $load5 = $this->kstat('unix:0:system_misc:avenrun_5min');
+    $load15 = $this->kstat('unix:0:system_misc:avenrun_15min');
+    $results['avg'] = array( round($load1/256, 2), round($load5/256, 2), round($load15/256, 2) );
+    return $results;
+  } 
+
+  function cpu_info () {
+    $results = array();
+    $ar_buf = array();
+
+    $results['model'] = execute_program('uname', '-i');
+    $results['cpuspeed'] = $this->kstat('cpu_info:0:cpu_info0:clock_MHz');
+    $results['cache'] = $this->kstat('cpu_info:0:cpu_info0:cpu_type');
+    $results['cpus'] = $this->kstat('unix:0:system_misc:ncpus');
+
+    return $results;
+  } 
+
+  function pci () {
+    // FIXME
+    $results = array();
+    return $results;
+  } 
+
+  function ide () {
+    // FIXME
+    $results = array();
+    return $results;
+  } 
+
+  function scsi () {
+    // FIXME
+    $results = array();
+    return $results;
+  } 
+
+  function usb () {
+    // FIXME
+    $results = array();
+    return $results;
+  } 
+
+  function sbus () {
+    $results = array();
+    $_results[0] = "";
+    // TODO. Nothing here yet. Move along.
+    $results = $_results;
+    return $results;
+  }
+
+  function network () {
+    $results = array();
+
+    $netstat = execute_program('netstat', '-ni | awk \'(NF ==10){print;}\'');
+    $lines = split("\n", $netstat);
+    $results = array();
+    for ($i = 0, $max = sizeof($lines); $i < $max; $i++) {
+      $ar_buf = preg_split("/\s+/", $lines[$i]);
+      if ((!empty($ar_buf[0])) && ($ar_buf[0] != 'Name')) {
+        $results[$ar_buf[0]] = array();
+
+        $results[$ar_buf[0]]['rx_bytes'] = 0;
+        $results[$ar_buf[0]]['rx_packets'] = $ar_buf[4];
+        $results[$ar_buf[0]]['rx_errs'] = $ar_buf[5];
+        $results[$ar_buf[0]]['rx_drop'] = 0;
+
+        $results[$ar_buf[0]]['tx_bytes'] = 0;
+        $results[$ar_buf[0]]['tx_packets'] = $ar_buf[6];
+        $results[$ar_buf[0]]['tx_errs'] = $ar_buf[7];
+        $results[$ar_buf[0]]['tx_drop'] = 0;
+
+        $results[$ar_buf[0]]['errs'] = $ar_buf[5] + $ar_buf[
+        7];
+        $results[$ar_buf[0]]['drop'] = 0;
+
+        preg_match('/^(\D+)(\d+)$/', $ar_buf[0], $intf);
+        $prefix = $intf[1] . ':' . $intf[2] . ':' . $intf[1] . $intf[2] . ':';
+        $cnt = $this->kstat($prefix . 'drop');
+
+        if ($cnt > 0) {
+          $results[$ar_buf[0]]['rx_drop'] = $cnt;
+        } 
+        $cnt = $this->kstat($prefix . 'obytes64');
+
+        if ($cnt > 0) {
+          $results[$ar_buf[0]]['tx_bytes'] = $cnt;
+        } 
+        $cnt = $this->kstat($prefix . 'rbytes64');
+
+        if ($cnt > 0) {
+          $results[$ar_buf[0]]['rx_bytes'] = $cnt;
+        }
+      } 
+    } 
+    return $results;
+  } 
+
+  function memory () {
+    $results['devswap'] = array();
+
+    $results['ram'] = array();
+
+    $pagesize = $this->kstat('unix:0:seg_cache:slab_size');
+    $results['ram']['total'] = $this->kstat('unix:0:system_pages:pagestotal') * $pagesize / 1024;
+    $results['ram']['used'] = $this->kstat('unix:0:system_pages:pageslocked') * $pagesize / 1024;
+    $results['ram']['free'] = $this->kstat('unix:0:system_pages:pagesfree') * $pagesize / 1024;
+    $results['ram']['shared'] = 0;
+    $results['ram']['buffers'] = 0;
+    $results['ram']['cached'] = 0;
+
+    $results['ram']['t_used'] = $results['ram']['used'] - $results['ram']['cached'] - $results['ram']['buffers'];
+    $results['ram']['t_free'] = $results['ram']['total'] - $results['ram']['t_used'];
+    $results['ram']['percent'] = round(($results['ram']['used'] * 100) / $results['ram']['total']);
+
+    $results['swap'] = array();
+    $results['swap']['total'] = $this->kstat('unix:0:vminfo:swap_avail') / 1024 / 1024;
+    $results['swap']['used'] = $this->kstat('unix:0:vminfo:swap_alloc') / 1024 / 1024;
+    $results['swap']['free'] = $this->kstat('unix:0:vminfo:swap_free') / 1024 / 1024;
+    $results['swap']['percent'] = round(($ar_buf[1] * 100) / $ar_buf[0]);
+    $results['swap']['percent'] = round(($results['swap']['used'] * 100) / $results['swap']['total']);
+    return $results;
+  } 
+
+  function filesystems () {
+    $df = execute_program('df', '-k');
+    $mounts = split("\n", $df);
+
+    $dftypes = execute_program('df', '-n');
+    $mounttypes = split("\n", $dftypes);
+
+    for ($i = 1, $j = 0, $max = sizeof($mounts); $i < $max; $i++) {
+      $ar_buf = preg_split('/\s+/', $mounts[$i], 6);
+      $ty_buf = split(':', $mounttypes[$i-1], 2);
+
+      if (hide_mount($ar_buf[5])) {
+        continue;
+      }
+
+      $results[$j] = array();
+
+      $results[$j]['disk'] = $ar_buf[0];
+      $results[$j]['size'] = $ar_buf[1];
+      $results[$j]['used'] = $ar_buf[2];
+      $results[$j]['free'] = $ar_buf[3];
+      $results[$j]['percent'] = round(($results[$j]['used'] * 100) / $results[$j]['size']);
+      $results[$j]['mount'] = $ar_buf[5];
+      $results[$j]['fstype'] = $ty_buf[1];
+      $j++;
+    } 
+    return $results;
+  } 
+  
+  function distro () {
+    $result = 'SunOS';  	
+    return($result);
+  }
+
+  function distroicon () {
+    $result = 'SunOS.png';
+    return($result);
+  }
+} 
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.WINNT.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.WINNT.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.WINNT.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.WINNT.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,315 @@
+<?php 
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+// 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.
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// WINNT implementation written by Carl C. Longnecker, longneck at iname.com
+// $Id: class.WINNT.inc.php,v 1.19 2006/04/22 16:47:25 bigmichi1 Exp $
+
+class sysinfo {
+  // $wmi holds the COM object that we pull all the WMI data from
+  var $wmi; 
+
+  // $wmidevices holds all devices, which are in the system
+  var $wmidevices;
+
+  // this constructor initialis the $wmi object
+  function sysinfo ()
+  {
+    // don't set this params for local connection, it will not work
+    $strHostname = '';
+    $strUser = '';
+    $strPassword = '';
+
+    // initialize the wmi object
+    $objLocator = new COM("WbemScripting.SWbemLocator");
+    if($strHostname == "") {
+        $this->wmi = $objLocator->ConnectServer();
+      } else{
+        $this->wmi = $objLocator->ConnectServer($strHostname, "rootcimv2", "$strHostname\$strUser", $strPassword);
+      }
+  } 
+
+  // private function for getting a list of values in the specified context, optionally filter this list, based on the list from second parameter
+  function _GetWMI($strClass, $strValue = array() ) {
+    $objWEBM = $this->wmi->Get($strClass);
+
+    if( PHP_VERSION < 5 ) {
+      $objProp = $objWEBM->Properties_;
+      $arrProp = $objProp->Next($objProp->Count);
+      $objWEBMCol = $objWEBM->Instances_();
+      $arrWEBMCol = $objWEBMCol->Next($objWEBMCol->Count);
+    } else {
+      $arrProp = $objWEBM->Properties_;
+      $arrWEBMCol = $objWEBM->Instances_();
+    }
+
+    foreach($arrWEBMCol as $objItem)
+    {
+        @reset($arrProp);
+        $arrInstance = array();
+        foreach($arrProp as $propItem)
+        {
+            eval("\$value = \$objItem->" .$propItem->Name .";");
+            if( empty( $strValue ) ) {
+              $arrInstance[$propItem->Name] = trim($value);
+            } else {
+              if( in_array( $propItem->Name, $strValue ) ) {
+                $arrInstance[$propItem->Name] = trim($value);
+              }
+            }
+        }
+        $arrData[] = $arrInstance;
+    }
+    return $arrData;
+  }
+
+  // private function for getting different device types from the system
+  function _devicelist ( $strType ) {
+    if( empty( $this->wmidevices ) ) {
+      $this->wmidevices = $this->_GetWMI( "Win32_PnPEntity", array( "Name", "PNPDeviceID" ) );
+    }
+
+    $list = array();
+    foreach ( $this->wmidevices as $device ) {
+      if ( substr( $device["PNPDeviceID"], 0, strpos( $device["PNPDeviceID"], "\\" ) + 1 ) == ( $strType . "\\" ) ) {
+        $list[] = $device["Name"];
+      } 
+    }
+
+    return $list;
+  }
+
+  // get our canonical hostname
+  function chostname ()
+  {
+    $buffer = $this->_GetWMI( "Win32_ComputerSystem", array( "Name" ) );
+    $result = $buffer[0]["Name"];
+    return gethostbyaddr(gethostbyname($result));
+  }
+
+  // get the IP address of our canonical hostname
+  function ip_addr ()
+  {
+    $buffer = $this->_GetWMI( "Win32_ComputerSystem", array( "Name" ) );
+    $result = $buffer[0]["Name"];
+    return gethostbyname($result);
+  }
+
+  function kernel ()
+  {
+    $buffer = $this->_GetWMI( "Win32_OperatingSystem", array( "Version", "ServicePackMajorVersion" ) );
+    $result = $buffer[0]["Version"];
+    if( $buffer[0]["ServicePackMajorVersion"] > 0 ) {
+      $result .= " SP" . $buffer[0]["ServicePackMajorVersion"];
+    }
+    return $result;
+  } 
+
+  // get the time the system is running
+  function uptime ()
+  {
+    $result = 0;
+    $buffer = $this->_GetWMI( "Win32_OperatingSystem", array( "LastBootUpTime" ) );
+
+    $year = intval(substr($buffer[0]["LastBootUpTime"], 0, 4));
+    $month = intval(substr($buffer[0]["LastBootUpTime"], 4, 2));
+    $day = intval(substr($buffer[0]["LastBootUpTime"], 6, 2));
+    $hour = intval(substr($buffer[0]["LastBootUpTime"], 8, 2));
+    $minute = intval(substr($buffer[0]["LastBootUpTime"], 10, 2));
+    $seconds = intval(substr($buffer[0]["LastBootUpTime"], 12, 2));
+
+    $hour -= date("Z") / 60 / 60;	// GMT-Offset
+
+    $boottime = mktime($hour, $minute, $seconds, $month, $day, $year);
+
+    $result = mktime() - $boottime;
+
+    return $result;
+  } 
+
+  // count the users, which are logged in
+  function users ()
+  {
+    if( !stristr( $this->kernel(), "2000 P" ) ) return "N.A."; 
+    $buffer = $this->_GetWMI( "Win32_PerfRawData_TermService_TerminalServices", array( "TotalSessions" ) );
+    return $buffer[0]["TotalSessions"];
+  } 
+
+  // get the load of the processors
+  function loadavg ($bar = false)
+  {
+    $buffer = $this->_GetWMI( "Win32_Processor", array( "LoadPercentage" ) );
+    $cpuload = array();
+    for( $i = 0; $i < count( $buffer ); $i++ ) {
+      $cpuload['avg'][] = $buffer[$i]["LoadPercentage"];
+    }
+    if ($bar) {
+      $cpuload['cpupercent'] = array_sum( $cpuload['avg'] ) / count( $buffer );
+    }
+    return $cpuload;
+  } 
+
+  // get some informations about the cpu's
+  function cpu_info ()
+  {
+    $buffer = $this->_GetWMI( "Win32_Processor", array( "Name", "L2CacheSize", "CurrentClockSpeed", "ExtClock" ) );
+    $results["cpus"] = 0;
+    foreach ($buffer as $cpu) {
+      $results["cpus"]++;
+      $results["model"] = $cpu["Name"];
+      $results["cache"] = $cpu["L2CacheSize"];
+      $results["cpuspeed"] = $cpu["CurrentClockSpeed"];
+      $results["busspeed"] = $cpu["ExtClock"];
+    } 
+    return $results;
+  } 
+
+  // get the pci devices from the system
+  function pci ()
+  {
+    $pci = $this->_devicelist( "PCI" );
+    return $pci;
+  } 
+
+  // get the ide devices from the system
+  function ide ()
+  {
+    $buffer = $this->_devicelist( "IDE" );
+    $ide = array();
+    foreach ( $buffer as $device ) {
+        $ide[]['model'] = $device;
+    } 
+    return $ide;
+  } 
+
+  // get the scsi devices from the system
+  function scsi ()
+  {
+    $scsi = $this->_devicelist( "SCSI" );
+    return $scsi;
+  } 
+
+  // get the usb devices from the system
+  function usb ()
+  {
+    $usb = $this->_devicelist( "USB" );
+    return $usb;
+  } 
+
+  // get the sbus devices from the system - currently not called
+  function sbus ()
+  {
+    $sbus = $this->_devicelist( "SBUS" );
+    return $sbus;
+  } 
+
+  // get the netowrk devices and rx/tx bytes
+  function network ()
+  {
+    $buffer = $this->_GetWMI( "Win32_PerfRawData_Tcpip_NetworkInterface" );
+    $results = array();
+    foreach ( $buffer as $device ) {
+      $dev_name = $device["Name"];
+      // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_perfrawdata_tcpip_networkinterface.asp
+      $results[$dev_name]['rx_bytes'] = $device["BytesReceivedPersec"];
+      $results[$dev_name]['rx_packets'] = $device["PacketsReceivedPersec"];
+      $results[$dev_name]['rx_errs'] = $device["PacketsReceivedErrors"];
+      $results[$dev_name]['rx_drop'] = $device["PacketsReceivedDiscarded"];
+
+      $results[$dev_name]['tx_bytes'] = $device["BytesSentPersec"];
+      $results[$dev_name]['tx_packets'] = $device["PacketsSentPersec"];
+
+      $results[$dev_name]['errs'] = $device["PacketsReceivedErrors"];
+      $results[$dev_name]['drop'] = $device["PacketsReceivedDiscarded"];
+    }
+    return $results;
+  } 
+
+  function memory ()
+  {
+    $buffer = $this->_GetWMI( "Win32_LogicalMemoryConfiguration", array( "TotalPhysicalMemory" ) );
+    $results['ram']['total'] = $buffer[0]["TotalPhysicalMemory"];
+
+    $buffer = $this->_GetWMI( "Win32_PerfRawData_PerfOS_Memory", array( "AvailableKBytes" ) );
+    $results['ram']['free'] = $buffer[0]["AvailableKBytes"];
+
+    $results['ram']['used'] = $results['ram']['total'] - $results['ram']['free'];
+    $results['ram']['t_used'] = $results['ram']['used'];
+    $results['ram']['t_free'] = $results['ram']['total'] - $results['ram']['t_used'];
+    $results['ram']['percent'] = ceil( ( $results['ram']['t_used'] * 100 ) / $results['ram']['total'] );
+    $results['swap']['total'] = 0;
+    $results['swap']['used'] = 0;
+    $results['swap']['free'] = 0;
+
+    $buffer = $this->_GetWMI( "Win32_PageFileUsage" ); // no need to filter, using nearly everything from output
+    $k = 0;
+    foreach ($buffer as $swapdevice) {
+      $results['devswap'][$k]['dev'] = $swapdevice["Name"];
+      $results['devswap'][$k]['total'] = $swapdevice["AllocatedBaseSize"] * 1024;
+      $results['devswap'][$k]['used'] = $swapdevice["CurrentUsage"] * 1024;
+      $results['devswap'][$k]['free'] = ( $swapdevice["AllocatedBaseSize"] - $swapdevice["CurrentUsage"] ) * 1024;
+      $results['devswap'][$k]['percent'] = ceil( $swapdevice["CurrentUsage"] / $swapdevice["AllocatedBaseSize"] );
+
+      $results['swap']['total'] += $results['devswap'][$k]['total'];
+      $results['swap']['used'] += $results['devswap'][$k]['used'];
+      $results['swap']['free'] += $results['devswap'][$k]['free'];
+      $k += 1;
+    } 
+    $results['swap']['percent'] = ceil( $results['swap']['used'] / $results['swap']['total'] * 100 );
+    return $results;
+  } 
+
+  // get the filesystem informations
+  function filesystems ()
+  {
+     $typearray = array("Unknown", "No Root Directory", "Removeable Disk",
+        "Local Disk", "Network Drive", "Compact Disc", "RAM Disk");
+     $floppyarray = array("Unknown", "5 1/4 in.", "3 1/2 in.", "3 1/2 in.",
+        "3 1/2 in.", "3 1/2 in.", "5 1/4 in.", "5 1/4 in.", "5 1/4 in.",
+        "5 1/4 in.", "5 1/4 in.", "Other", "HD", "3 1/2 in.", "3 1/2 in.",
+        "5 1/4 in.", "5 1/4 in.", "3 1/2 in.", "3 1/2 in.", "5 1/4 in.",
+        "3 1/2 in.", "3 1/2 in.", "8 in.");
+
+    $buffer = $this->_GetWMI( "Win32_LogicalDisk" , array( "Name", "Size", "FreeSpace", "FileSystem", "DriveType", "MediaType" ) );
+
+    $k = 0;
+    foreach ( $buffer as $filesystem ) {
+      if ( hide_mount( $filesystem["Name"] ) ) {
+        continue;
+      }
+      $results[$k]['mount'] = $filesystem["Name"];
+      $results[$k]['size'] = $filesystem["Size"] / 1024;
+      $results[$k]['used'] = ( $filesystem["Size"] - $filesystem["FreeSpace"] ) / 1024;
+      $results[$k]['free'] = $filesystem["FreeSpace"] / 1024;
+      @$results[$k]['percent'] = ceil( $results[$k]['used'] / $results[$k]['size'] * 100 );  // silence this line, nobody is having a floppy in the drive everytime
+      $results[$k]['fstype'] = $filesystem["FileSystem"];
+      $results[$k]['disk'] = $typearray[$filesystem["DriveType"]];
+      if ( $filesystem["DriveType"] == 2 ) $results[$k]['disk'] .= " (" . $floppyarray[$filesystem["MediaType"]] . ")";
+      $k += 1;
+    } 
+    return $results;
+  } 
+
+  function distro ()
+  {
+    $buffer = $this->_GetWMI( "Win32_OperatingSystem", array( "Caption" ) );
+    return $buffer[0]["Caption"];
+  } 
+
+  function distroicon ()
+  {
+    return 'xp.gif';
+  } 
+} 
+
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.parseProgs.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.parseProgs.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.parseProgs.inc.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/class.parseProgs.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,133 @@
+<?php
+
+class Parser {
+
+    var $debug	= false;
+    var $df_param;
+    
+    function parse_lspci() {
+
+	$results = array();
+
+        if ($_results = execute_program('lspci', '', $this->debug)) {
+	    $lines = split("\n", $_results);
+	    for ($i = 0, $max = sizeof($lines); $i < $max; $i++) {
+		list($addr, $name) = explode(' ', trim($lines[$i]), 2);
+		//if (!preg_match('/bridge/i', $name) && !preg_match('/USB/i', $name)) {
+		// remove all the version strings
+		$name = preg_replace('/\(.*\)/', '', $name);
+		// is addr really usefull for this??? i think it's not
+		// $results[] = $addr . ' ' . $name;
+		$results[] = $name;
+		//}
+    	    }
+	}
+	
+	if( empty( $results ) ) {
+	    return false;
+	} else {
+	    asort( $results );
+	    return $results;
+	}
+    }
+
+    function parse_pciconf() {
+    
+        $results = array();
+
+	if($buf = execute_program("pciconf", "-lv", $this->debug)) {
+    	    $buf = explode("\n", $buf); $s = 0;
+    	    foreach($buf as $line) {
+        	if (preg_match("/(.*) = '(.*)'/", $line, $strings)) {
+            	    if (trim($strings[1]) == "vendor") {
+                	$results[$s] = trim($strings[2]);
+            	    } elseif (trim($strings[1]) == "device") {
+                	$results[$s] .= " - " . trim($strings[2]);
+                	$s++;
+            	    }
+        	}
+    	    }
+	}
+
+	if( empty( $results ) ) {
+	    return false;
+	} else {
+	    asort( $results );
+	    return $results;
+	}
+    }
+
+    function parse_filesystems() {
+
+	global $show_bind, $show_inodes;
+
+        $j = 0;
+
+        $df = execute_program('df', '-k' . $this->df_param );
+        $df = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY);
+
+	if( $show_inodes ) {
+	    $df2 = execute_program('df', '-i' . $this->df_param );
+	    $df2 = preg_split("/\n/", $df2, -1, PREG_SPLIT_NO_EMPTY);
+	}
+
+        $mount = execute_program('mount');
+        $mount = preg_split("/\n/", $mount, -1, PREG_SPLIT_NO_EMPTY);
+	
+	foreach( $df as $df_line) {
+	    $df_buf1  = preg_split("/(\%\s)/", $df_line, 2);
+	    if( count($df_buf1) != 2) {
+		continue;
+	    }
+	    
+	    preg_match("/(.*)(\s+)(([0-9]+)(\s+)([0-9]+)(\s+)([0-9]+)(\s+)([0-9]+)$)/", $df_buf1[0], $df_buf2);
+	    $df_buf = array($df_buf2[1], $df_buf2[4], $df_buf2[6], $df_buf2[8], $df_buf2[10], $df_buf1[1]);
+	    
+	    if( $show_inodes ) {
+		preg_match_all("/([0-9]+)%/", $df2[$j + 1], $inode_buf, PREG_SET_ORDER);
+	    }
+	    
+	    if( count($df_buf) == 6 ) {
+		if( hide_mount( $df_buf[5] ) ) {
+		    continue;
+		}
+		
+		$df_buf[0] = trim( str_replace("\$", "\\$", $df_buf[0] ) );
+		$df_buf[5] = trim( $df_buf[5] );
+		
+		$current = 0;		
+		foreach( $mount as $mount_line ) {
+		    $current++;
+		    
+		    if ( preg_match("#" . $df_buf[0] . " on " . $df_buf[5] . " type (.*) \((.*)\)#", $mount_line, $mount_buf) ) {
+			$mount_buf[1] .= "," . $mount_buf[2];
+	    	    } elseif ( !preg_match("#" . $df_buf[0] . "(.*) on " . $df_buf[5] . " \((.*)\)#", $mount_line, $mount_buf) ) {
+		    	continue;
+        	    }
+
+		    if ( $show_bind || !stristr($mount_buf[2], "bind")) {
+        		$results[$j] = array();
+			$results[$j]['disk'] = str_replace( "\\$", "\$", $df_buf[0] );
+    			$results[$j]['size'] = $df_buf[1];
+		        $results[$j]['used'] = $df_buf[2];
+		        $results[$j]['free'] = $df_buf[3];
+		        $results[$j]['percent'] = round(($results[$j]['used'] * 100) / $results[$j]['size']);
+		        $results[$j]['mount'] = $df_buf[5];
+		        $results[$j]['fstype'] = substr( $mount_buf[1], 0, strpos( $mount_buf[1], "," ) );
+		        $results[$j]['options'] = substr( $mount_buf[1], strpos( $mount_buf[1], "," ) + 1, strlen( $mount_buf[1] ) );
+			if( $show_inodes && isset($inode_buf[ count( $inode_buf ) - 1][1]) ) {
+			    $results[$j]['inodes'] = $inode_buf[ count( $inode_buf ) - 1][1];
+			}
+		        $j++;
+			unset( $mount[$current - 1] );
+			sort( $mount );
+			break;
+		    }
+		}
+	    }
+	}
+	return $results;
+    }
+
+}
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/common_functions.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/common_functions.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/common_functions.php (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/common_functions.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,349 @@
+<?php 
+// phpSysInfo - A PHP System Information Script
+// http://phpsysinfo.sourceforge.net/
+// 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.
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// $Id: common_functions.php,v 1.42 2006/04/17 13:03:38 bigmichi1 Exp $
+// HTML/XML Comment
+function created_by ()
+{
+  global $VERSION;
+  return "<!--\n\tCreated By: phpSysInfo - $VERSION\n\thttp://phpsysinfo.sourceforge.net/\n-->\n\n";
+} 
+// usefull during development
+error_reporting(E_ALL | E_NOTICE);
+
+// print out the bar graph
+// $value as full percentages
+// $maximim as current maximum 
+// $b as scale factor
+// $type as filesystem type
+function create_bargraph ($value, $maximum, $b, $type = "", $red_limit=90, $yellow_limit=75)
+{
+  global $webpath;
+  
+  $textdir = direction();
+
+  $imgpath = $webpath . 'templates/' . TEMPLATE_SET . '/images/';
+  //$imgpath = 'modules/sysinfo/tinfo/templates/' . TEMPLATE_SET . '/images/';
+  $maximum == 0 ? $barwidth = 0 : $barwidth = round((100  / $maximum) * $value) * $b;
+  //$red = 90 * $b;
+  $red = $red_limit * $b;
+  //$yellow = 75 * $b;
+  $yellow = $yellow_limit * $b;
+
+  if (!file_exists(APP_ROOT . "/templates/" . TEMPLATE_SET . "/images/nobar_left.gif")) {
+    if ($barwidth == 0) {
+      return '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'bar_' . $textdir['left'] . '.gif" alt="">' 
+           . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'bar_middle.gif" width="1" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'bar_' . $textdir['right'] . '.gif" alt="">';
+    } elseif (file_exists(APP_ROOT . "/templates/" . TEMPLATE_SET . "/images/yellowbar_left.gif") && $barwidth > $yellow && $barwidth < $red) {
+      return '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'yellowbar_' . $textdir['left'] . '.gif" alt="">' 
+           . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'yellowbar_middle.gif" width="' . $barwidth . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'yellowbar_' . $textdir['right'] . '.gif" alt="">';
+    } elseif (($barwidth < $red) || ($type == "iso9660") || ($type == "CDFS")) {
+      return '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'bar_' . $textdir['left'] . '.gif" alt="">' 
+           . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'bar_middle.gif" width="' . $barwidth . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'bar_' . $textdir['right'] . '.gif" alt="">';
+    } else {
+      return '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'redbar_' . $textdir['left'] . '.gif" alt="">' 
+           . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'redbar_middle.gif" width="' . $barwidth . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'redbar_' . $textdir['right'] . '.gif" alt="">';
+    }
+  } else {
+    if ($barwidth == 0) {
+      return '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'nobar_' . $textdir['left'] . '.gif" alt="">' 
+           . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'nobar_middle.gif" width="' . (100 * $b) . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'nobar_' . $textdir['right'] . '.gif" alt="">';
+    } elseif (file_exists(APP_ROOT . "/templates/" . TEMPLATE_SET . "/images/yellowbar_left.gif") && $barwidth > $yellow && $barwidth < $red) {
+      return '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'yellowbar_' . $textdir['left'] . '.gif" alt="">' 
+           . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'yellowbar_middle.gif" width="' . $barwidth . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'nobar_middle.gif" width="' . ((100 * $b) - $barwidth) . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'nobar_' . $textdir['right'] . '.gif" alt="">';
+    } elseif (($barwidth < $red) || $type == "iso9660" || ($type == "CDFS")) {
+      return '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'bar_' . $textdir['left'] . '.gif" alt="">' 
+           . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'bar_middle.gif" width="' . $barwidth . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'nobar_middle.gif" width="' . ((100 * $b) - $barwidth) . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'nobar_' . $textdir['right'] . '.gif" alt="">';
+    } elseif ($barwidth == (100 * $b)) {
+      return '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'redbar_' . $textdir['left'] . '.gif" alt="">' 
+           . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'redbar_middle.gif" width="' . (100 * $b) . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'redbar_' . $textdir['right'] . '.gif" alt="">';
+    } else {
+      return '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'redbar_' . $textdir['left'] . '.gif" alt="">' 
+           . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'redbar_middle.gif" width="' . $barwidth . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'nobar_middle.gif" width="' . ((100 * $b) - $barwidth) . '" alt="">' 
+	   . '<img height="' . BAR_HEIGHT . '" src="' . $imgpath . 'nobar_' . $textdir['right'] . '.gif" alt="">';
+    }
+  }
+} 
+
+function create_bargraph_grad( $value, $maximum, $b, $type = "" ) {
+  global $webpath;
+
+  $maximum == 0 ? $barwidth = 0 : $barwidth = round((100  / $maximum) * $value);
+  $startColor = '0ef424'; // green
+  $endColor = 'ee200a'; // red
+  if ($barwidth > 100) {
+    $barwidth = 0;
+  }
+
+  return '<img height="' . BAR_HEIGHT . '" width="300" src="' . $webpath . 'includes/indicator.php?height=' . BAR_HEIGHT . '&amp;percent=' . $barwidth . '&amp;color1=' . $startColor . '&amp;color2=' . $endColor . '" alt="">';
+}
+
+function direction() {
+  global $text_dir;
+
+  if(!isset($text_dir) || $text_dir == "ltr") {
+    $result['direction'] = "ltr";
+    $result['left'] = "left";
+    $result['right'] = "right";
+  } else {
+    $result['direction'] = "rtl";
+    $result['left'] = "right";
+    $result['right'] = "left";
+  }
+  
+  return $result;
+}
+
+// Find a system program.  Do path checking
+function find_program ($program)
+{
+  global $addpaths;
+
+  $path = array('/bin', '/sbin', '/usr/bin', '/usr/sbin', '/usr/local/bin', '/usr/local/sbin');
+
+  if( isset($addpaths) && is_array($addpaths) ) {
+    $path = array_merge( $path, $addpaths );
+  }
+
+  if (function_exists("is_executable")) {
+    while ($this_path = current($path)) {
+      if (is_executable("$this_path/$program")) {
+        return "$this_path/$program";
+      } 
+      next($path);
+    } 
+  } else {
+    return strpos($program, '.exe');
+  } ;
+
+  return;
+} 
+// Execute a system program. return a trim()'d result.
+// does very crude pipe checking.  you need ' | ' for it to work
+// ie $program = execute_program('netstat', '-anp | grep LIST');
+// NOT $program = execute_program('netstat', '-anp|grep LIST');
+function execute_program ($programname, $args = '', $booErrorRep = true )
+{
+  global $error;
+  $buffer = '';
+  $program = find_program($programname);
+
+  if (!$program) {
+    if( $booErrorRep ) {
+      $error->addError( 'find_program(' . $programname . ')', 'program not found on the machine', __LINE__, __FILE__);
+    }
+    return;
+  } 
+  
+  // see if we've gotten a |, if we have we need to do patch checking on the cmd
+  if ($args) {
+    $args_list = split(' ', $args);
+    for ($i = 0; $i < count($args_list); $i++) {
+      if ($args_list[$i] == '|') {
+        $cmd = $args_list[$i + 1];
+        $new_cmd = find_program($cmd);
+        $args = ereg_replace("\| $cmd", "| $new_cmd", $args);
+      } 
+    } 
+  } 
+  // we've finally got a good cmd line.. execute it
+  if ($fp = popen("($program $args > /dev/null) 3>&1 1>&2 2>&3", 'r')) {
+    while (!feof($fp)) {
+      $buffer .= fgets($fp, 4096);
+    }
+    pclose($fp);
+    $buffer = trim($buffer);
+    if (!empty($buffer)) {
+      if( $booErrorRep ) {
+        $error->addError( $program, $buffer, __LINE__, __FILE__);
+      }
+    }
+  }
+  if ($fp = popen("$program $args", 'r')) {
+    $buffer = "";
+    while (!feof($fp)) {
+      $buffer .= fgets($fp, 4096);
+    }
+    pclose($fp);
+  }
+  $buffer = trim($buffer);
+  return $buffer;
+} 
+
+// A helper function, when passed a number representing KB,
+// and optionally the number of decimal places required,
+// it returns a formated number string, with unit identifier.
+function format_bytesize ($kbytes, $dec_places = 2)
+{
+  global $text;
+  $spacer = '&nbsp;';
+  if ($kbytes > 1048576) {
+    $result = sprintf('%.' . $dec_places . 'f', $kbytes / 1048576);
+    $result .= $spacer . $text['gb'];
+  } elseif ($kbytes > 1024) {
+    $result = sprintf('%.' . $dec_places . 'f', $kbytes / 1024);
+    $result .= $spacer . $text['mb'];
+  } else {
+    $result = sprintf('%.' . $dec_places . 'f', $kbytes);
+    $result .= $spacer . $text['kb'];
+  } 
+  return $result;
+} 
+
+function get_gif_image_height($image)
+{ 
+  // gives the height of the given GIF image, by reading it's LSD (Logical Screen Discriptor)
+  // by Edwin Meester aka MillenniumV3
+  // Header: 3bytes 	Discription
+  // 3bytes 	Version
+  // LSD:		2bytes 	Logical Screen Width
+  // 2bytes 	Logical Screen Height
+  // 1bit 		Global Color Table Flag
+  // 3bits   Color Resolution
+  // 1bit		Sort Flag
+  // 3bits		Size of Global Color Table
+  // 1byte		Background Color Index
+  // 1byte		Pixel Aspect Ratio
+  // Open Image
+  $fp = fopen($image, 'rb'); 
+  // read Header + LSD
+  $header_and_lsd = fread($fp, 13);
+  fclose($fp); 
+  // calc Height from Logical Screen Height bytes
+  $result = ord($header_and_lsd{8}) + ord($header_and_lsd{9}) * 255;
+  return $result;
+} 
+
+// Check if a string exist in the global $hide_mounts.
+// Return true if this is the case.
+function hide_mount($mount) {
+	global $hide_mounts;
+	if (isset($hide_mounts) && is_array($hide_mounts) && in_array($mount, $hide_mounts)) {
+		return true;
+	}
+	else {
+		return false;
+	}
+}
+
+function uptime($timestamp) {
+  global $text;
+  $uptime = '';
+    
+  $min = $timestamp / 60;
+  $hours = $min / 60;
+  $days = floor($hours / 24);
+  $hours = floor($hours - ($days * 24));
+  $min = floor($min - ($days * 60 * 24) - ($hours * 60));
+
+  if ($days != 0) {
+    $uptime .= $days. "&nbsp;" . $text['days'] . "&nbsp;";
+  }
+
+  if ($hours != 0) {
+    $uptime .= $hours . "&nbsp;" . $text['hours'] . "&nbsp;";
+  }
+  
+  $uptime .= $min . "&nbsp;" . $text['minutes'];
+  return $uptime;
+}
+
+//Replace some chars which are not valid in xml with iso-8859-1 encoding
+function replace_specialchars(&$xmlstring) {
+    $xmlstring = str_replace( chr(174), "(R)", $xmlstring );
+    $xmlstring = str_replace( chr(169), "(C)", $xmlstring );
+}
+
+// find duplicate entrys and count them, show this value befor the duplicated name
+function finddups( $arrInput ) {
+  $result = array();
+  $buffer = array_count_values($arrInput);
+  foreach ($buffer as $key => $value) {
+    if( $value > 1 ) {
+      $result[] = "(" . $value . "x) " . $key;
+    } else {
+      $result[] = $key;
+    }
+  }
+  return $result;
+}
+
+function rfts( $strFileName, $intLines = 0, $intBytes = 4096, $booErrorRep = true ) {
+	global $error;
+	$strFile = "";
+	$intCurLine = 1;
+  
+	if( file_exists( $strFileName ) ) {
+		if( $fd = fopen( $strFileName, 'r' ) ) {
+			while( !feof( $fd ) ) {
+				$strFile .= fgets( $fd, $intBytes );
+				if( $intLines <= $intCurLine && $intLines != 0 ) {
+					break;
+				} else {
+					$intCurLine++;
+				}
+			}
+			fclose( $fd );
+		} else {
+			if( $booErrorRep ) {
+				$error->addError( 'fopen(' . $strFileName . ')', 'file can not read by phpsysinfo', __LINE__, __FILE__ );
+			}
+		return "ERROR";
+    }
+	} else {
+		if( $booErrorRep ) {
+			$error->addError( 'file_exists(' . $strFileName . ')', 'the file does not exist on your machine', __LINE__, __FILE__ );
+		}
+		return "ERROR";
+	}
+	return $strFile;
+}
+
+function gdc( $strPath, $booErrorRep = true ) {
+  global $error;
+  $arrDirectoryContent = array();
+  
+  if( is_dir( $strPath ) ) {
+    if( $handle = opendir( $strPath ) ) {
+      while( ( $strFile = readdir( $handle ) ) !== false ) {
+        if( $strFile != "." && $strFile != ".." && $strFile != "CVS" ) {
+          $arrDirectoryContent[] = $strFile;
+	}
+      }
+      closedir( $handle );
+    } else {
+      if( $booErrorRep ) {
+        $error->addError( 'opendir(' . $strPath . ')', 'directory can not be read by phpsysinfo', __LINE__, __FILE__ );
+      }
+    }
+  } else {
+    if( $booErrorRep ) {
+      $error->addError( 'is_dir(' . $strPath . ')', 'directory does not exist on your machine', __LINE__, __FILE__ );
+    }
+  }
+  
+  return $arrDirectoryContent;
+}
+?>

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/distros.ini
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/distros.ini?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/dashboard/phpsysinfo/distros.ini (added)
+++ freepbx-modules/trunk/modules/dashboard/phpsysinfo/distros.ini Mon Apr  7 13:18:05 2008
@@ -1,0 +1,77 @@
+; linux-distros.ini - Defines known linux distros for phpSysInfo.
+; http://phpsysinfo.sourceforge.net/
+; $Id: distros.ini,v 1.9 2007/06/17 12:07:34 bigmichi1 Exp $
+;
+
+[Debian]
+Name = "Debian"
+Image = "Debian.png"
+Files = "/etc/debian_release;/etc/debian_version"
+
+[SUSE LINUX]
+Image = "Suse.png"
+Files = "/etc/SuSE-release;/etc/UnitedLinux-release"
+
+[Mandrage]
+Image = "Mandrake.png"
+Files = "/etc/mandrake-release"
+
+[Gentoo]
+Image = "Gentoo.png"
+Files = "/etc/gentoo-release"
+
+[RedHat]
+Image = "Redhat.png"
+Files = "/etc/redhat-release;/etc/redhat_version"
+
+[Fedora]
+Image = "Fedora.png"
+Files = "/etc/fedora-release"
+
+[FedoraCore]
+Image = "Fedora.png"
+Files = "/etc/fedora-release"
+
+[Slackware]
+Image = "Slackware.png"
+Files = "/etc/slackware-release;/etc/slackware-version"
+
+[Trustix]
+Image = "Trustix.gif"
+Files = "/etc/trustix-release;/etc/trustix-version"
+
+[FreeEOS]
+Image = "free-eos.png"
+Files = "/etc/eos-version"
+
+[Arch]
+Image = "Arch.gif"
+Files = "/etc/arch-release"
+
+[Cobalt]
+Image = "Cobalt.png"
+Files = "/etc/cobalt-release"
+
+[LinuxFromScratch]
+Image = "lfs.png"
+Files = "/etc/lfs-release"
+
+[Rubix]
+Image   = "Rubix.png"
+Files   = "/etc/rubix-version"
+
+[Ubuntu]
+Image = "Ubuntu.gif"
+Files = "/etc/lsb-release"
+
+[PLD]
+Image = "PLD.gif"
+Files = "/etc/pld-release"
+
+[CentOS]
+Image = "CentOS.png"
+Files = "/etc/redhat-release;/etc/redhat_version"
+
+[RedHatEnterpriseES] 
+Image = "Redhat.png" 
+Files = "/etc/redhat-release;/etc/redhat_version"

Added: freepbx-modules/trunk/modules/dashboard/phpsysinfo/index.html
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dashboard/phpsysinfo/index.html?rev=5512&op=file
==============================================================================
    (empty)

Added: freepbx-modules/trunk/modules/daynight/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/daynight/functions.inc.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/daynight/functions.inc.php (added)
+++ freepbx-modules/trunk/modules/daynight/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,273 @@
+<?php
+ /* $Id: functions.inc.php 4024 2007-06-09 03:09:16Z p_lindheimer $ */
+
+// Class To Create, Access and Change DAYNIGHT objects in the dialplan
+//
+class dayNightObject {
+
+	var $id;
+
+	// contstructor
+	function dayNightObject($item) {
+		$this->id = $item;
+	}
+		
+	function getState() {
+		global $astman;
+
+		if ($astman != null) {
+			$mode = $astman->database_get("DAYNIGHT","C".$this->id);
+			if ($mode != "DAY" && $mode != "NIGHT") {
+				// TODO: should this return an error?
+				return false;
+			} else {
+				return $mode;
+			}
+		} else {
+			die_freepbx("No open connection to asterisk manager, can not access object.");
+		}
+	}
+
+	function setState($state) {
+		global $astman;
+
+		if ($this->getState() === false) {
+			die_freepbx("You must create the object before setting the state.");
+			return false;
+		} else {
+			switch ($state) {
+				case "DAY":
+				case "NIGHT":
+					if ($astman != null) {
+						$astman->database_put("DAYNIGHT","C".$this->id,$state);
+					} else {
+						die_freepbx("No open connection to asterisk manager, can not access object.");
+					}
+					break;
+				default:
+					die_freepbx("Invalid state: $state");
+					break;
+			}
+		}
+	}
+
+	function create($state="DAY") {
+		global $astman;
+
+		$current_state = $this->getState();
+		if ($current_state !== false) {
+			die_freepbx("Object already exists and is in state: $current_state, you must delete it first");
+			return false;
+		} else {
+			switch ($state) {
+				case "DAY":
+				case "NIGHT":
+					if ($astman != null) {
+						$astman->database_put("DAYNIGHT","C".$this->id,$state);
+					} else {
+						die_freepbx("No open connection to asterisk manager, can not access object.");
+					}
+					break;
+				default:
+					die_freepbx("Invalid state: $state");
+					break;
+			}
+		}
+	}
+
+	function del() {
+		global $astman;
+
+		if ($astman != null) {
+			$astman->database_del("DAYNIGHT","C".$this->id);
+		} else {
+			die_freepbx("No open connection to asterisk manager, can not access object.");
+		}
+	}
+}
+
+// The destinations this module provides
+// returns a associative arrays with keys 'destination' and 'description'
+function daynight_destinations() {
+
+	$list = daynight_list();
+	foreach ($list as $item) {
+		$dests = daynight_get_obj($item['ext']);
+		if (!isset($dests['day']) || !isset($dests['night'])) {
+			continue;
+		}
+		$description = $item['dest'] != ""?$item['dest']:"Day/Night Switch";
+		$description = "(".$item['ext'].") ".$description;
+		$extens[] = array('destination' => 'app-daynight,'.$item['ext'].',1', 'description' => $description);
+	}
+
+	// return an associative array with destination and description
+	if (isset($extens)) 
+		return $extens;
+	else
+		return null;
+}
+
+function daynight_get_config($engine) {
+	global $ext;
+
+	switch($engine) {
+		case "asterisk":
+
+			$id = "app-daynight"; // The context to be included
+			$ext->addInclude('from-internal-additional', $id); // Add the include from from-internal
+
+			$list = daynight_list();
+
+			foreach ($list as $item) {
+				$dests = daynight_get_obj($item['ext']);
+				$ext->add($id, $item['ext'], '', new ext_gotoif('$["${DB(DAYNIGHT/C${EXTEN})}" = "NIGHT"]',$dests['night'],$dests['day']));
+			}
+
+			daynight_toggle();
+
+			break;
+	}
+}
+
+function daynight_toggle() {
+	global $ext;
+
+	$fcc = new featurecode('daynight', 'toggle-mode');
+	$c = $fcc->getCodeActive();
+	unset($fcc);
+
+	if (!empty($c)) {
+		$id = "app-daynight-toggle"; // The context to be included
+
+		$ext->addInclude('from-internal-additional', $id); // Add the include from from-internal
+
+		$list = daynight_list();
+		$passwords = daynight_passwords();
+		foreach ($list as $item) {
+			$index = $item['ext'];
+			$ext->add($id, $c.$index, '', new ext_answer(''));
+			$ext->add($id, $c.$index, '', new ext_wait('1'));
+
+			if (isset($passwords[$index]) && trim($passwords[$index]) != "" && ctype_digit(trim($passwords[$index]))) {
+				$ext->add($id, $c.$index, '', new ext_authenticate($passwords[$index]));
+			}
+			$ext->add($id, $c.$index, '', new ext_setvar('INDEX', $index));	
+			$ext->add($id, $c.$index, '', new ext_goto($id.',s,1'));
+		}
+
+		$c='s';
+		$ext->add($id, $c, '', new ext_setvar('DAYNIGHTMODE', '${DB(DAYNIGHT/C${INDEX})}'));	
+		$ext->add($id, $c, '', new ext_gotoif('$["${DAYNIGHTMODE}" = "NIGHT"]', 'day', 'night'));
+
+		$ext->add($id, $c, 'day', new ext_setvar('DB(DAYNIGHT/C${INDEX})', 'DAY'));	
+		$ext->add($id, $c, '', new ext_playback('beep&silence/1&day&reception&digits/${INDEX}&enabled'));
+		$ext->add($id, $c, '', new ext_hangup(''));
+
+		$ext->add($id, $c, 'night', new ext_setvar('DB(DAYNIGHT/C${INDEX})', 'NIGHT'));	
+		$ext->add($id, $c, '', new ext_playback('beep&silence/1&beep&silence/1&day&reception&digits/${INDEX}&disabled'));
+		$ext->add($id, $c, '', new ext_hangup(''));
+	}
+}
+
+function daynight_get_avail() {
+	global $db;
+
+	$sql = "SELECT ext FROM daynight ORDER BY ext";
+	$results = $db->getCol($sql);
+	if(DB::IsError($results)) {
+		$results = array();
+	}
+
+	for ($i=0;$i<=9;$i++) {
+		if (!in_array($i,$results)) {
+			$list[]=$i;
+		}
+	}
+	return $list;
+}
+
+//get the existing daynight codes
+function daynight_list() {
+	$results = sql("SELECT ext, dest FROM daynight WHERE dmode = 'fc_description' ORDER BY ext","getAll",DB_FETCHMODE_ASSOC);
+	if(is_array($results)){
+		foreach($results as $result){
+			$list[] = $result;
+		}
+	}
+	if (isset($list)) {
+		return $list;
+	} else { 
+		return array();
+	}
+}
+
+//get the existing password codes
+function daynight_passwords() {
+	$results = sql("SELECT ext, dest FROM daynight WHERE dmode = 'password'","getAll",DB_FETCHMODE_ASSOC);
+	if(is_array($results)){
+		foreach($results as $result){
+			$list[$result['ext']] = $result['dest'];
+		}
+	}
+	if (isset($list)) {
+		return $list;
+	} else { 
+		return array();
+	}
+}
+
+function daynight_edit($post, $id=0) {
+
+	// TODO: Probably have separate add and edit (and change in page.daynight.php also)
+	//       Need to set the day/night mode in the system if new
+
+	// Delete all the old dests
+	sql("DELETE FROM daynight WHERE dmode IN ('day', 'night', 'password', 'fc_description') AND ext = '$id'");
+
+	$day   = isset($post[$post['goto0'].'0'])?$post[$post['goto0'].'0']:'';
+	$night = isset($post[$post['goto1'].'1'])?$post[$post['goto1'].'1']:'';
+
+	sql("INSERT INTO daynight (ext, dmode, dest) VALUES ('$id', 'day', '$day')");
+	sql("INSERT INTO daynight (ext, dmode, dest) VALUES ('$id', 'night', '$night')");
+
+	if (isset($post['password']) && trim($post['password'] != "")) {
+		$password = trim($post['password']);
+		sql("INSERT INTO daynight (ext, dmode, dest) VALUES ('$id', 'password', '$password')");
+	}
+	if (isset($post['fc_description']) && trim($post['fc_description'] != "")) {
+		$fc_description = trim($post['fc_description']);
+		sql("INSERT INTO daynight (ext, dmode, dest) VALUES ('$id', 'fc_description', '$fc_description')");
+	}
+
+	$dn = new dayNightObject($id);
+	$dn->del();
+	$dn->create($post['state']);
+
+	needreload();
+}
+
+function daynight_del($id){
+
+	// TODO: delete ASTDB entry when deleting the mode
+	//
+	$results = sql("DELETE FROM daynight WHERE ext = \"$id\"","query");
+}
+
+function daynight_get_obj($id=0) {
+	global $db;
+
+	$sql = "SELECT dmode, dest FROM daynight WHERE dmode IN ('day', 'night', 'password', 'fc_description') AND ext = '$id' ORDER BY dmode";
+	$res = $db->getAll($sql, DB_FETCHMODE_ASSOC);
+	if(DB::IsError($res)) {
+		return null;
+	}
+		foreach($res as $pair) {
+			$dmodes[$pair['dmode']] = $pair['dest'];
+		}
+		$dn = new dayNightObject($id);
+		$dmodes['state'] = $dn->getState();
+
+		return $dmodes;
+}
+?>

Added: freepbx-modules/trunk/modules/daynight/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/daynight/install.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/daynight/install.php (added)
+++ freepbx-modules/trunk/modules/daynight/install.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,23 @@
+<?php
+
+$sql = "CREATE TABLE IF NOT EXISTS daynight 
+        (
+				ext varchar(10) NOT NULL default '',
+				dmode varchar(40) NOT NULL default '',
+			  dest varchar(255) NOT NULL default '',
+				PRIMARY KEY (ext, dmode)
+			  );
+			 ";
+$check = $db->query($sql);
+if(DB::IsError($check)) {
+	die_freepbx("Can not create daynight table");
+}
+
+// Day / Night Mode Control
+$fcc = new featurecode('daynight', 'toggle-mode');
+$fcc->setDescription('Day/Night Control Toggle');
+$fcc->setDefault('*28');
+$fcc->update();
+unset($fcc);	
+
+?>

Added: freepbx-modules/trunk/modules/daynight/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/daynight/module.xml?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/daynight/module.xml (added)
+++ freepbx-modules/trunk/modules/daynight/module.xml Mon Apr  7 13:18:05 2008
@@ -1,0 +1,25 @@
+<module>
+	<rawname>daynight</rawname>
+	<name>Day Night Mode</name>
+	<version>1.0.2.4</version>
+	<type>setup</type>
+	<category>Inbound Call Control</category>
+	<description>
+		Day / Night control - allows for two destinations to be chosen and provides a feature code
+		that toggles between the two destinations.
+	</description>
+	<changelog>
+		*1.0.2.4* #2414 fix other unmatched ) syntax error
+		*1.0.2.3* #2414 fix unmatched ) syntax error
+		*1.0.2.2* bump for rc1
+		*1.0.2.1* added xml attribute needsenginedb, fixed some undefined vars
+		*1.0.2* Added red/green color coding of rnav to see current mode
+		*1.0.1* #2047 got day/night reversed
+		*1.0.0* First release for FreePBX 2.3 
+	</changelog>
+	<menuitems>
+		<daynight needsenginedb="yes">Day/Night Control</daynight>
+	</menuitems>
+	<location>release/2.3/daynight-1.0.2.3.tgz</location>
+	<md5sum>c8d4405e75c36add2dfff837b60505f5</md5sum>
+</module>

Added: freepbx-modules/trunk/modules/daynight/page.daynight.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/daynight/page.daynight.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/daynight/page.daynight.php (added)
+++ freepbx-modules/trunk/modules/daynight/page.daynight.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,225 @@
+<?php 
+/* $Id: page.ivr.php 3790 2007-02-16 18:52:53Z p_lindheimer $ */
+//Copyright (C) 2007 Atengo LLC (info at atengo.net)
+//
+//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.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+$dispnum = "daynight"; //used for switch on config.php
+
+$action = isset($_REQUEST['action'])?$_REQUEST['action']:'';
+$password = isset($_REQUEST['password'])?$_REQUEST['password']:'';
+$fc_description = isset($_REQUEST['fc_description'])?$_REQUEST['fc_description']:'';
+
+isset($_REQUEST['itemid'])?$itemid=mysql_real_escape_string($_REQUEST['itemid']):$itemid='';
+
+
+$fcc = new featurecode('daynight', 'toggle-mode');
+$fc = $fcc->getCodeActive();
+unset($fcc);
+
+$daynightcodes = daynight_list();
+?>
+
+</div> <!-- end content div so we can display rnav properly-->
+
+<!-- right side menu -->
+<div class="rnav"><ul>
+    <li><a id="<?php echo ($itemid=='' ? 'current':'') ?>" href="config.php?display=<?php echo urlencode($dispnum)?>&action=add"><?php echo _("Add Day/Night Code")?></a></li>
+<?php
+if (isset($daynightcodes)) {
+	foreach ($daynightcodes as $code) {
+		$dnobj = daynight_get_obj($code['ext']);
+		$color = $dnobj['state'] == 'DAY' ? "style='color:green'" : "style='color:red'";
+		echo "<li><a $color id=\"".($itemid==$code['ext'] ? 'current':'')."\" href=\"config.php?display=".urlencode($dispnum)."&itemid=".urlencode($code['ext'])."&action=edit\">($fc{$code['ext']}) {$code['dest']}</a></li>";
+	}
+}
+?>
+</ul></div>
+<?php
+
+switch ($action) {
+	case "add":
+		daynight_show_edit($_POST,'add');
+		break;
+	case "edit":
+		daynight_show_edit($_POST);
+		break;
+	case "edited":
+			daynight_edit($_POST,$itemid);
+			redirect_standard('itemid');
+			break;
+	case "delete":
+			daynight_del($itemid);
+			redirect_standard();
+			break;
+	default:
+		daynight_show_edit($_POST,'add');
+		break;
+}
+
+function daynight_show_edit($post, $add="") {
+	global $db;
+	global $itemid;
+
+	$fcc = new featurecode('daynight', 'toggle-mode');
+	$code = $fcc->getCodeActive().$itemid;
+	unset($fcc);
+
+	$dests = daynight_get_obj($itemid);
+	$password = isset($dests['password'])?$dests['password']:'';
+	$fc_description = isset($dests['fc_description'])?$dests['fc_description']:'';
+	$state = isset($dests['state'])?$dests['state']:'DAY';
+?>
+	<div class="content">
+	<h2><?php echo _("Day / Night Mode Control"); ?></h2>
+
+<?php
+	$delURL = $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'].'&action=delete';
+?>
+<?php		if ($itemid != ""){ ?>
+	<p><a href="<?php echo $delURL ?>"><?php echo _("Delete Day/Night Feature Code:")?> <?php echo $code; ?></a></p>
+<?php		} ?>
+
+	<form name="prompt" action="<?php $_SERVER['PHP_SELF'] ?>" method="post" onsubmit="return prompt_onsubmit();">
+	<input type="hidden" name="action" value="edited" />
+	<input type="hidden" name="display" value="daynight" />
+	<input name="Submit" type="submit" style="display:none;" value="save" />
+	<table>
+	<tr>
+		<td colspan=2><hr />
+		</td>
+	</tr>
+	<tr>
+		<td colspan="2">	
+		<input name="Submit" type="submit" value="<?php echo _("Save")?>">
+		<?php if ($itemid != '') echo "&nbsp ".sprintf(_("Use feature code: %s to toggle DAY/NIGHT mode"),"<strong>".$code."</strong>")?>
+		</td>
+	</tr>
+	<tr>
+		<td colspan=2>
+		<hr />
+		</td>
+	</tr>
+	<tr>
+		<td><a href="#" class="info"><?php echo _("Day/Night Feature Code Index:")?>
+		<span><?php echo _("There are a total of 10 Feature code objects, 0-9, each can control a call flow and be toggled using the day/night feature code plus the index.")?>
+		</span></a>
+		</td>
+		<td>
+<?php
+			if ($add == "add" && $itemid =="") {
+?>
+			<select name="itemid"/>
+			<?php
+				$ids = daynight_get_avail();
+				foreach ($ids as $id) {
+					echo '<option value="'.$id.'" >'.$id.'</option>';
+				}
+			?>
+			</select>
+<?php
+			} else {
+?>
+		<input readonly="yes" size="1" type="text" name="itemid" value="<?php  echo $itemid ?>">
+<?php
+		}
+?>
+		</td>
+	</tr>
+	<tr>
+		<td><a href="#" class="info"><?php echo _("Description")?>:<span><?php echo _('Description for this Day/Night Control')?></span></a></td>
+		<td><input size="40" type="text" name="fc_description" value="<?php  echo $fc_description ?>">
+		</td>
+	</tr>
+	<tr>
+		<td><a href="#" class="info"><?php echo _("Current Mode:")?>
+		<span><?php echo _("This will change the current state for this Day/Night Mode Control, or set the intial state when creating a new one.")?>
+		</span></a>
+		</td>
+		<td>
+			<select name="state"/>
+				<option value="DAY" <?php echo ($state == 'DAY' ? 'SELECTED':'') ?> >Day</option> 
+				<option value="NIGHT" <?php echo ($state == 'NIGHT' ? 'SELECTED':'') ?> >Night</option> 
+			</select>
+		</td>
+	</tr>
+	<tr>
+		<td><a href="#" class="info"><?php echo _("Optional Password")?>:<span><?php echo _('You can optionally include a password to authenticate before toggling the day/night mode. If left blank anyone can use the feature code will be un-protected')?></span></a></td>
+		<td><input size="12" type="text" name="password" value="<?php  echo $password ?>">
+		</td>
+	</tr>
+	<tr>
+		<td colspan=2>
+		<hr />
+		</td>
+	</tr>
+<?php
+	// Draw the destinations
+	// returns an array, $dest['day'], $dest['night']
+	// and puts null if nothing set
+
+	drawdestinations(0, _("DAY"),   isset($dests['day'])?$dests['day']:'');
+	drawdestinations(1, _("NIGHT"), isset($dests['night'])?$dests['night']:'');
+
+	//TODO: Check to make sure a destination radio button was checked, and if custom, that it was not blank
+	//
+?>
+	<tr>
+		<td colspan=2>	
+		<input name="Submit" type="submit" value="<?php echo _("Save")?>">
+		<?php if ($itemid != '') echo "&nbsp ".sprintf(_("Use feature code: %s to toggle DAY/NIGHT mode"),"<strong>".$code."</strong>")?>
+		</td>
+	</tr>
+	<tr>
+		<td colspan=2>
+		<hr />
+		</td>
+	</tr>
+	</table>
+
+	<script language="javascript">
+	<!--
+	var theForm = document.prompt;
+
+	function prompt_onsubmit() {
+		var msgInvalidPassword = "<?php echo _('Please enter a valid numeric password, only numbers are allowed'); ?>";
+
+		defaultEmptyOK = true;
+		if (!isInteger(theForm.password.value))
+			return warnInvalid(theForm.password, msgInvalidPassword);
+		return true;
+	}
+	//-->
+	</script>
+
+	</form>
+	</div>
+<?php
+} //daynight function
+
+
+// count is for the unique identifier
+// dest is the target
+//
+function drawdestinations($count, $mode, $dest) { ?>
+	<tr> 
+		<td style="text-align:right;">
+		<a href="#" class="info"><strong><?php echo _("$mode")?></strong><span><?php echo _("Destination to use when set to $mode mode")?></span></a>
+		</td>
+		<td> 
+			<table> <?php echo drawselects($dest,$count); ?> 
+			</table> 
+		</td>
+	</tr>
+	<tr><td colspan=2><hr /></td></tr>
+<?php
+}
+?>

Added: freepbx-modules/trunk/modules/daynight/uninstall.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/daynight/uninstall.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/daynight/uninstall.php (added)
+++ freepbx-modules/trunk/modules/daynight/uninstall.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,9 @@
+<?php
+
+$fcc = new featurecode('daynight', 'toggle-mode');
+$fcc->delete();
+unset($fcc);	
+
+sql('DROP TABLE daynight');
+
+?>

Modified: freepbx-modules/trunk/modules/dictate/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dictate/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/dictate/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/dictate/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -21,7 +21,6 @@
 							$fname($fc);
 					} else {
 						$ext->add('from-internal-additional', 'debug', '', new ext_noop($modulename.": No func $fname"));
-						var_dump($item);
 					}	
 				}
 			}
@@ -38,12 +37,12 @@
 	$ext->addInclude('from-internal-additional', $id); // Add the include from from-internal
 	$ext->add($id, $c, '', new ext_answer(''));
 	$ext->add($id, $c, '', new ext_macro('user-callerid'));
-	$ext->add($id, $c, '', new ext_NoOp('CallerID is ${CALLERID(num)}'));
-	$ext->add($id, $c, '', new ext_setvar('DICTENABLED','${DB(AMPUSER/${CALLERID(num)}/dictate/enabled)}'));
+	$ext->add($id, $c, '', new ext_NoOp('CallerID is ${AMPUSER}'));
+	$ext->add($id, $c, '', new ext_setvar('DICTENABLED','${DB(AMPUSER/${AMPUSER}/dictate/enabled)}'));
 	$ext->add($id, $c, '', new ext_gotoif('$[$["x${DICTENABLED}"="x"]|$["x${DICTENABLED}"="xdisabled"]]','nodict', 'dictok'));
 	$ext->add($id, $c, 'nodict', new ext_playback('feature-not-avail-line'));
 	$ext->add($id, $c, '', new ext_hangup(''));
-	$ext->add($id, $c, 'dictok', new ext_dictate($asterisk_conf['astvarlibdir'].'/sounds/dictate/${CALLERID(num)}'));
+	$ext->add($id, $c, 'dictok', new ext_dictate($asterisk_conf['astvarlibdir'].'/sounds/dictate/${AMPUSER}'));
 	$ext->add($id, $c, '', new ext_macro('hangupcall'));
 }
 
@@ -55,17 +54,17 @@
 	$ext->addInclude('from-internal-additional', $id); // Add the include from from-internal
 	$ext->add($id, $c, '', new ext_answer(''));
 	$ext->add($id, $c, '', new ext_macro('user-callerid'));
-	$ext->add($id, $c, '', new ext_NoOp('CallerID is ${CALLERID(num)}'));
-	$ext->add($id, $c, '', new ext_setvar('DICTENABLED','${DB(AMPUSER/${CALLERID(num)}/dictate/enabled)}'));
+	$ext->add($id, $c, '', new ext_NoOp('CallerID is ${AMPUSER}'));
+	$ext->add($id, $c, '', new ext_setvar('DICTENABLED','${DB(AMPUSER/${AMPUSER}/dictate/enabled)}'));
 	$ext->add($id, $c, '', new ext_gotoif('$[$["x${DICTENABLED}"="x"]|$["x${DICTENABLED}"="xdisabled"]]','nodict', 'dictok'));
 	$ext->add($id, $c, 'nodict', new ext_playback('feature-not-avail-line'));
 	$ext->add($id, $c, '', new ext_hangup(''));
 	$ext->add($id, $c, 'dictok', new ext_read('DICTFILE','enter-filename-short'));
-	$ext->add($id, $c, '', new ext_setvar('DICTEMAIL','${DB(AMPUSER/${CALLERID(num)}/dictate/email)}'));
-	$ext->add($id, $c, '', new ext_setvar('DICTFMT','${DB(AMPUSER/${CALLERID(num)}/dictate/format)}'));
-	$ext->add($id, $c, '', new ext_setvar('NAME','${DB(AMPUSER/${CALLERID(num)}/cidname)}'));
+	$ext->add($id, $c, '', new ext_setvar('DICTEMAIL','${DB(AMPUSER/${AMPUSER}/dictate/email)}'));
+	$ext->add($id, $c, '', new ext_setvar('DICTFMT','${DB(AMPUSER/${AMPUSER}/dictate/format)}'));
+	$ext->add($id, $c, '', new ext_setvar('NAME','${DB(AMPUSER/${AMPUSER}/cidname)}'));
 	$ext->add($id, $c, '', new ext_playback('dictation-being-processed'));
-	$ext->add($id, $c, '', new ext_system($asterisk_conf['astvarlibdir'].'/bin/audio-email.pl --file '.$asterisk_conf['astvarlibdir'].'/sounds/dictate/${CALLERID(num)}/${DICTFILE}.raw --attachment dict-${DICTFILE} --format ${DICTFMT} --to ${DICTEMAIL} --subject "Dictation from ${NAME} Attached"'));
+	$ext->add($id, $c, '', new ext_system($asterisk_conf['astvarlibdir'].'/bin/audio-email.pl --file '.$asterisk_conf['astvarlibdir'].'/sounds/dictate/${AMPUSER}/${DICTFILE}.raw --attachment dict-${DICTFILE} --format ${DICTFMT} --to ${DICTEMAIL} --subject "Dictation from ${NAME} Attached"'));
 	$ext->add($id, $c, '', new ext_playback('dictation-sent'));
 	$ext->add($id, $c, '', new ext_macro('hangupcall'));
 }
@@ -84,6 +83,7 @@
 	// On a 'new' user, 'tech_hardware' is set, and there's no extension. Hook into the page.
 	if ($tech_hardware != null || $pagename == 'users') {
 		dictation_applyhooks();
+		$currentcomponent->addprocessfunc('dictate_configprocess', 5);
 	} elseif ($action=="add") {
 		// We don't need to display anything on an 'add', but we do need to handle returned data.
 		$currentcomponent->addprocessfunc('dictate_configprocess', 5);
@@ -167,7 +167,7 @@
 	// If it's blank, set it to disabled
 	if (!$ena) { $ena = "disabled"; }
 	// Default format is ogg
-	if (!$format) { $foramt = "ogg"; }
+	if (!$format) { $format = "ogg"; }
 
 	return array('enabled' => $ena, 'format' => $format, 'email' => $email);
 }

Modified: freepbx-modules/trunk/modules/dictate/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dictate/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/dictate/module.xml (original)
+++ freepbx-modules/trunk/modules/dictate/module.xml Mon Apr  7 13:18:05 2008
@@ -1,17 +1,20 @@
 <module>
 	<rawname>dictate</rawname>
 	<name>Dictation</name>
-	<version>1.1.1</version>
+	<version>1.1.2.3</version>
 	<type>setup</type>
-	<category>Provides a Feature Code</category>
+	<category>Internal Options &amp; Configuration</category>
 	<changelog>
+		*1.1.2.3* #2312 fix dictate in devicesandusers mode
+		*1.1.2.2* changed categories
+		*1.1.2.1* bump for rc1
+		*1.1.2* changed ${CALLERID(number)} to ${AMPUSER} to accomodate CID number masquerading
 		*1.1.1* Fix for Dictation not appearing on User page when in Device and User mode.
 		*1.1* Fix changes not sticking when creating an extension, replace Rob-sounds with Allison-sounds.
 		*1.0.1* Replaced 'invalid extension' with 'feature not available on this line' when disabled
 		*1.0.0* Original Release
 	</changelog>
 	<description>This uses the app_dictate module of Asterisk to let users record dictate into their phones. When complete, the dictations can be emailed to an email address specified in the extension page.</description>
-	<location>release/2.2/dictate-1.1.1.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Dictation</info>
-	<md5sum>20d218be75eb99a5c9c8528b561a18cf</md5sum>
+	<location>release/2.3/dictate-1.1.2.2.tgz</location>
+	<md5sum>81f0b4ecff6a96b6a271122eec532fe0</md5sum>
 </module>

Added: freepbx-modules/trunk/modules/dictate/sounds/dictation-being-processed.sln
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dictate/sounds/dictation-being-processed.sln?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/dictate/sounds/dictation-being-processed.sln
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: freepbx-modules/trunk/modules/dictate/sounds/dictation-sent.sln
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/dictate/sounds/dictation-sent.sln?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/dictate/sounds/dictation-sent.sln
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: freepbx-modules/trunk/modules/disa/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/disa/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/disa/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/disa/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -56,7 +56,10 @@
 					$ext->add('disa', $item['disa_id'], '', new ext_setvar('TIMEOUT(response)', $thisitem['resptimeout']));
 					
 					if ($nopass) {
-						$ext->add('disa', $item['disa_id'], '', new ext_disa('no-password|'.$item['context']));
+						if ($item['cid']) {
+						 	$ext->add('disa', $item['disa_id'], '', new ext_setvar('CALLERID(all)', $item['cid'])); 
+						}
+						$ext->add('disa', $item['disa_id'], '', new ext_disa('no-password,'.$item['context']));
 					} else {
 						$ext->add('disa', $item['disa_id'], '', new ext_playback('enter-password'));
 						$ext->add('disa', $item['disa_id'], '', new ext_disa('/etc/asterisk/disa-'.$item['disa_id'].'.conf'));

Modified: freepbx-modules/trunk/modules/disa/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/disa/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/disa/install.php (original)
+++ freepbx-modules/trunk/modules/disa/install.php Mon Apr  7 13:18:05 2008
@@ -11,18 +11,18 @@
 	$sql = 'ALTER TABLE disa ADD COLUMN digittimeout INT DEFAULT "5"';
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getDebugInfo());
+		die_freepbx($result->getDebugInfo());
 	}
 	// Response Timeout
 	$sql = 'ALTER TABLE disa ADD COLUMN resptimeout INT DEFAULT "10"';
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getDebugInfo());
+		die_freepbx($result->getDebugInfo());
 	}
 	$sql = 'ALTER TABLE disa ADD COLUMN needconf VARCHAR ( 10 )  DEFAULT ""';
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getDebugInfo());
+		die_freepbx($result->getDebugInfo());
 	}
 }
 

Modified: freepbx-modules/trunk/modules/disa/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/disa/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/disa/module.xml (original)
+++ freepbx-modules/trunk/modules/disa/module.xml Mon Apr  7 13:18:05 2008
@@ -1,18 +1,20 @@
 <module>
 	<rawname>disa</rawname>
 	<name>DISA</name>
-	<version>2.2.1</version>
+	<version>2.2.2.3</version>
 	<type>setup</type>
-	<category>Remote Access</category>
+	<category>Internal Options &amp; Configuration</category>
 	<menuitems>
 		<disa>DISA</disa>
 	</menuitems>
 	<description>DISA Allows you 'Direct Inward System Access'. This gives you the ability to have an option on an IVR that gives you a dial tone, and you're able to dial out from the freePBX machine as if you were connected to a standard extension. It appears as a Destination.</description>
 	<changelog>
-	*2.2.1* Add he_IL translation
-	*2.2* First release for FreePBX 2.2 - Fixed compatibility issue with new UI
+		*2.2.2.3* #2463 Set CID when no pin
+		*2.2.2.2* #2172 deprecated use of |, changed category
+		*2.2.2.1* bump for rc1
+		*2.2.2* bump so higher that 2.2 branch
+		*2.2*   First release for FreePBX 2.2 - Fixed compatibility issue with new UI
 	</changelog>
-	<location>release/2.2/disa-2.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-DISA</info>
-	<md5sum>252f44814486f33bb06b71485678c79f</md5sum>
+	<location>release/2.3/disa-2.2.2.2.tgz</location>
+	<md5sum>b0dc8c41a7e727f9c25fb5cfecde7c75</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/donotdisturb/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/donotdisturb/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/donotdisturb/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/donotdisturb/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -38,7 +38,7 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_setvar('DB(DND/${CALLERID(number)})', 'YES')); // $cmd,n,Set(...=YES)
+	$ext->add($id, $c, '', new ext_setvar('DB(DND/${AMPUSER})', 'YES')); // $cmd,n,Set(...=YES)
 	$ext->add($id, $c, '', new ext_playback('do-not-disturb&activated')); // $cmd,n,Playback(...)
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
 }
@@ -53,7 +53,7 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_dbdel('DND/${CALLERID(number)}')); // $cmd,n,DBdel(..)
+	$ext->add($id, $c, '', new ext_dbdel('DND/${AMPUSER}')); // $cmd,n,DBdel(..)
 	$ext->add($id, $c, '', new ext_playback('do-not-disturb&de-activated')); // $cmd,n,Playback(...)
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
 }

Modified: freepbx-modules/trunk/modules/donotdisturb/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/donotdisturb/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/donotdisturb/module.xml (original)
+++ freepbx-modules/trunk/modules/donotdisturb/module.xml Mon Apr  7 13:18:05 2008
@@ -1,10 +1,15 @@
 <module>
 	<rawname>donotdisturb</rawname>
 	<name>Do-Not-Disturb (DND)</name>
-	<version>1.0.1</version>
+	<version>1.0.2.2</version>
+	<changelog>
+		*1.0.2.2* changed category
+		*1.0.2.1* bump for rc1
+		*1.0.2* changed ${CALLERID(number)} to ${AMPUSER} to accomodate CID number masquerading
+		*1.0.1* First release for 2.2
+	</changelog>
 	<type>setup</type>
-	<category>Call Management</category>
-	<location>release/donotdisturb-1.0.1.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Features</info>
-	<md5sum>f2f87161fc0ac2fde9048543c3fd4fd0</md5sum>
+	<category>Internal Options &amp; Configuration</category>
+	<location>release/2.3/donotdisturb-1.0.2.1.tgz</location>
+	<md5sum>480cd7593b131c61a96147b7fa7cda59</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/donotdisturb/uninstall.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/donotdisturb/uninstall.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/donotdisturb/uninstall.php (original)
+++ freepbx-modules/trunk/modules/donotdisturb/uninstall.php Mon Apr  7 13:18:05 2008
@@ -1,18 +1,15 @@
 <?php
 
-require_once('common/php-asmanager.php');
+// TODO, is this needed...?
+// is this global...? what if we include this files
+// from a function...?
+global $astman;
 
 // remove all D-N-D options in effect on extensions
-$astman = new AGI_AsteriskManager();
-if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {
-
+if ($astman) {
 	$astman->database_deltree('DND');
-
 } else {
-
 	fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
-
 }
-$astman->disconnect();
 
 ?>

Modified: freepbx-modules/trunk/modules/featurecodeadmin/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/featurecodeadmin/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/featurecodeadmin/module.xml (original)
+++ freepbx-modules/trunk/modules/featurecodeadmin/module.xml Mon Apr  7 13:18:05 2008
@@ -1,18 +1,23 @@
 <module>
 	<rawname>featurecodeadmin</rawname>
 	<name>Feature Code Admin</name>
-	<version>1.0.4</version>
+	<version>1.0.5.3</version>
+	<candisable>no</candisable>
+	<canuninstall>no</canuninstall>
 	<type>setup</type>
 	<category>Basic</category>
 	<menuitems>
 		<featurecodeadmin>Feature Codes</featurecodeadmin>
 	</menuitems>
+	<location>release/2.3/featurecodeadmin-1.0.5.2.tgz</location>
 	<changelog>
+	  *1.0.5.3* changed categories
+	  *1.0.5.2* added canuninstall = no for module admin, bump for rc1
+	  *1.0.5.1* added candisable = no for module admin
+		*1.0.5* Fix install bug with featurecode release
 		*1.0.4* Add support for duplicate feature codes
 		*1.0.3* Add he_IL translation
 		*1.0.2* Fix minor font/display issues
 	</changelog>
-	<location>release/2.2/featurecodeadmin-1.0.3.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-FeatureCodeAdmin</info>
-	<md5sum>e2c8211003d680c4c85070b502029ed0</md5sum>
+	<md5sum>8dbe40b6f108043e995092ae5100b26c</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/findmefollow/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/findmefollow/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/findmefollow/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/findmefollow/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -2,6 +2,10 @@
 
 // The destinations this module provides
 // returns a associative arrays with keys 'destination' and 'description'
+/*
+
+// Remove destinations, use from-did-direct in core for 2.3 and on
+
 function findmefollow_destinations() {
 	//get the list of findmefollow
 	$results = findmefollow_full_list();
@@ -10,12 +14,13 @@
 	if (isset($results)) {
 		foreach($results as $result){
 				$thisgrp = findmefollow_get(ltrim($result['0']));
-				$extens[] = array('destination' => 'ext-findmefollow,'.ltrim($result['0']).',1', 'description' => $thisgrp['grppre'].' <'.ltrim($result['0']).'>');
+				$extens[] = array('destination' => 'ext-findmefollow,FM'.ltrim($result['0']).',1', 'description' => $thisgrp['grppre'].' <'.ltrim($result['0']).'>');
 		}
 	}
 	
 	return isset($extens)?$extens:null;
 }
+*/
 
 /* 	Generates dialplan for findmefollow
 	We call this with retrieve_conf
@@ -56,7 +61,17 @@
 					}
 
 
-					$ext->add($contextname, $grpnum, '', new ext_macro('user-callerid'));
+					// Direct target to Follow-Me come here bypassing the followme/ddial conditional check
+					//
+					$ext->add($contextname, 'FM'.$grpnum, '', new ext_goto("$grpnum,FM$grpnum"));
+
+					//
+					// If the followme is configured for extension dialing to go to the the extension and not followme then
+					// go there. This is often used in VmX Locater functionality when the user does not want the followme
+					// to automatically be called but only if chosen by the caller as an alternative to going to voicemail
+					//
+					$ext->add($contextname, $grpnum, '', new ext_gotoif('$[ "${DB(AMPUSER/'.$grpnum.'/followme/ddial)}" = "EXTENSION" ]', 'ext-local,'.$grpnum.',1'));
+					$ext->add($contextname, $grpnum, 'FM'.$grpnum, new ext_macro('user-callerid'));
 
 					// block voicemail until phone is answered at which point a macro should be called on the answering
 					// line to clear this flag so that subsequent transfers can occur, if already set by a the caller
@@ -100,8 +115,10 @@
 						$ext->add($contextname, $grpnum, '', new ext_setvar("__ALERT_INFO", str_replace(';', '\;', $dring) ));
 					}
 					// If pre_ring is set, then ring this number of seconds prior to moving on
-					$ext->add($contextname, $grpnum, '', new ext_gotoif('$[$[ "${DB(AMPUSER/'.$grpnum.'/followme/prering)}" = "0" ] | $[ "${DB(AMPUSER/'.$grpnum.'/followme/prering)}" = "" ]] ', 'skipsimple'));
-					$ext->add($contextname, $grpnum, '', new ext_macro('simple-dial',$grpnum.',${DB(AMPUSER/'."$grpnum/followme/prering)}"));
+					if ((isset($strategy) ? substr($strategy,0,strlen('ringallv2')) : '') != 'ringallv2') {
+						$ext->add($contextname, $grpnum, '', new ext_gotoif('$[$[ "${DB(AMPUSER/'.$grpnum.'/followme/prering)}" = "0" ] | $[ "${DB(AMPUSER/'.$grpnum.'/followme/prering)}" = "" ]] ', 'skipsimple'));
+						$ext->add($contextname, $grpnum, '', new ext_macro('simple-dial',$grpnum.',${DB(AMPUSER/'."$grpnum/followme/prering)}"));
+					}
 
 					// recording stuff
 					$ext->add($contextname, $grpnum, 'skipsimple', new ext_setvar('RecordMethod','Group'));
@@ -109,6 +126,7 @@
 
 					// group dial
 					$ext->add($contextname, $grpnum, '', new ext_setvar('RingGroupMethod',$strategy));
+					$ext->add($contextname, $grpnum, '', new ext_setvar('_FMGRP',$grpnum));
 					if ((isset($annmsg) ? $annmsg : '') != '') {
 						// should always answer before playing anything, shouldn't we ?
 						$ext->add($contextname, $grpnum, '', new ext_gotoif('$[$["${DIALSTATUS}" = "ANSWER"] | $["foo${RRNODEST}" != "foo"]]','DIALGRP'));			
@@ -127,13 +145,19 @@
 					    ext_gotoif('$[ "${DB(AMPUSER/'.$grpnum.'/followme/grpconf)}" = "ENABLED" ]', 'doconfirm'));
 
 					// Normal call
-					$ext->add($contextname, $grpnum, '', new 
-					    ext_macro('dial','${DB(AMPUSER/'."$grpnum/followme/grptime)},$dialopts,".'${DB(AMPUSER/'."$grpnum/followme/grplist)}"));
+					if ((isset($strategy) ? substr($strategy,0,strlen('ringallv2')) : '') != 'ringallv2') {
+						$ext->add($contextname, $grpnum, '', new ext_macro('dial','${DB(AMPUSER/'."$grpnum/followme/grptime)},$dialopts,".'${DB(AMPUSER/'."$grpnum/followme/grplist)}"));
+					} else {
+						$ext->add($contextname, $grpnum, '', new ext_macro('dial','$[ ${DB(AMPUSER/'.$grpnum.'/followme/grptime)} + ${DB(AMPUSER/'.$grpnum.'/followme/prering)} ],'.$dialopts.',${DB(AMPUSER/'.$grpnum.'/followme/grplist)}'));
+					}
 					$ext->add($contextname, $grpnum, '', new ext_goto('nextstep'));
 
 					// Call Confirm call
-					$ext->add($contextname, $grpnum, 'doconfirm', new 
-					    ext_macro('dial-confirm','${DB(AMPUSER/'."$grpnum/followme/grptime)},$dialopts,".'${DB(AMPUSER/'."$grpnum/followme/grplist)},".$grpnum));
+					if ((isset($strategy) ? substr($strategy,0,strlen('ringallv2')) : '') != 'ringallv2') {
+						$ext->add($contextname, $grpnum, 'doconfirm', new ext_macro('dial-confirm','${DB(AMPUSER/'."$grpnum/followme/grptime)},$dialopts,".'${DB(AMPUSER/'."$grpnum/followme/grplist)},".$grpnum));
+					} else {
+						$ext->add($contextname, $grpnum, 'doconfirm', new ext_macro('dial-confirm','$[ ${DB(AMPUSER/'.$grpnum.'/followme/grptime)} + ${DB(AMPUSER/'.$grpnum.'/followme/prering)} ],'.$dialopts.',${DB(AMPUSER/'.$grpnum.'/followme/grplist)},'.$grpnum));
+					}
 
 					$ext->add($contextname, $grpnum, 'nextstep', new ext_setvar('RingGroupMethod',''));
 
@@ -158,19 +182,25 @@
 	}
 }
 
-function findmefollow_add($grpnum,$strategy,$grptime,$grplist,$postdest,$grppre='',$annmsg='',$dring,$needsconf,$remotealert,$toolate,$ringing,$pre_ring) {
+function findmefollow_add($grpnum,$strategy,$grptime,$grplist,$postdest,$grppre='',$annmsg='',$dring,$needsconf,$remotealert,$toolate,$ringing,$pre_ring,$ddial) {
 	global $amp_conf;
 	global $astman;
 
-	$sql = "INSERT INTO findmefollow (grpnum, strategy, grptime, grppre, grplist, annmsg, postdest, dring, needsconf, remotealert, toolate, ringing, pre_ring) VALUES (".$grpnum.", '".str_replace("'", "''", $strategy)."', ".str_replace("'", "''", $grptime).", '".str_replace("'", "''", $grppre)."', '".str_replace("'", "''", $grplist)."', '".str_replace("'", "''", $annmsg)."', '".str_replace("'", "''", $postdest)."', '".str_replace("'", "''", $dring)."', '$needsconf', '$remotealert', '$toolate', '$ringing', '$pre_ring')";
+	$sql = "INSERT INTO findmefollow (grpnum, strategy, grptime, grppre, grplist, annmsg, postdest, dring, needsconf, remotealert, toolate, ringing, pre_ring) VALUES ('".str_replace("'", "''",$grpnum)."', '".str_replace("'", "''", $strategy)."', ".str_replace("'", "''", $grptime).", '".str_replace("'", "''", $grppre)."', '".str_replace("'", "''", $grplist)."', '".str_replace("'", "''", $annmsg)."', '".str_replace("'", "''", $postdest)."', '".str_replace("'", "''", $dring)."', '$needsconf', '$remotealert', '$toolate', '$ringing', '$pre_ring')";
 	$results = sql($sql);
 
 	if ($astman) {
 		$astman->database_put("AMPUSER",$grpnum."/followme/prering",isset($pre_ring)?$pre_ring:'');
 		$astman->database_put("AMPUSER",$grpnum."/followme/grptime",isset($grptime)?$grptime:'');
 		$astman->database_put("AMPUSER",$grpnum."/followme/grplist",isset($grplist)?$grplist:'');
+
+		$needsconf = isset($needsconf)?$needsconf:'';
 		$confvalue = ($needsconf == 'CHECKED')?'ENABLED':'DISABLED';
-		$astman->database_put("AMPUSER",$grpnum."/followme/grpconf",isset($needsconf)?$confvalue:'');
+		$astman->database_put("AMPUSER",$grpnum."/followme/grpconf",$confvalue);
+
+		$ddial      = isset($ddial)?$ddial:'';
+		$ddialvalue = ($ddial == 'CHECKED')?'EXTENSION':'DIRECT';
+		$astman->database_put("AMPUSER",$grpnum."/followme/ddial",$ddialvalue);
 	} else {
 		fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
 	}
@@ -180,20 +210,17 @@
 	global $amp_conf;
 	global $astman;
 
-	$results = sql("DELETE FROM findmefollow WHERE grpnum = $grpnum","query");
+	$results = sql("DELETE FROM findmefollow WHERE grpnum = '".str_replace("'", "''", $grpnum)."'","query");
 
 	if ($astman) {
-		$astman->database_del("AMPUSER",$grpnum."/followme/prering");
-		$astman->database_del("AMPUSER",$grpnum."/followme/grptime");
-		$astman->database_del("AMPUSER",$grpnum."/followme/grplist");
-		$astman->database_del("AMPUSER",$grpnum."/followme/grpconf");
+		$astman->database_deltree("AMPUSER/".$grpnum."/followme");
 	} else {
 		fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
 	}
 }
 
 function findmefollow_full_list() {
-	$results = sql("SELECT grpnum FROM findmefollow ORDER BY grpnum","getAll",DB_FETCHMODE_ASSOC);
+	$results = sql("SELECT grpnum FROM findmefollow ORDER BY CAST(grpnum as UNSIGNED)","getAll",DB_FETCHMODE_ASSOC);
 	foreach ($results as $result) {
 		if (isset($result['grpnum']) && checkRange($result['grpnum'])) {
 			$grps[] = array($result['grpnum']);
@@ -208,17 +235,17 @@
 function findmefollow_list() {
 
         global $db;
-        $sql = "SELECT grpnum FROM findmefollow ORDER BY grpnum";
+        $sql = "SELECT grpnum FROM findmefollow ORDER BY CAST(grpnum as UNSIGNED)";
         $results = $db->getCol($sql);
         if(DB::IsError($results)) {
                 $results = null;
         }
         if (isset($results)) {
-		foreach($results as $result) {
-			if (checkRange($result)){
-				$grps[] = $result;
-			}
-		}
+					foreach($results as $result) {
+						if (checkRange($result)){
+							$grps[] = $result;
+						}
+					}
         }
         if (isset($grps)) {
 		sort($grps); // hmm, should be sorted already
@@ -257,11 +284,15 @@
 // in sync. Ideally, anything that changes the astdb should change SQL. (in some ways, these should both
 // not be here but ...
 //
+// Need to go back and confirm at some point that the $check_astdb error is still there and deal with it.
+// as variables like $ddial get introduced to only be in astdb, the result array will not include them
+// if not able to get to astdb. (I suspect in 2.2 and beyond this may all be fixed).
+//
 function findmefollow_get($grpnum, $check_astdb=0) {
 	global $amp_conf;
 	global $astman;
 
-	$results = sql("SELECT grpnum, strategy, grptime, grppre, grplist, annmsg, postdest, dring, needsconf, remotealert, toolate, ringing, pre_ring FROM findmefollow WHERE grpnum = $grpnum","getRow",DB_FETCHMODE_ASSOC);
+	$results = sql("SELECT grpnum, strategy, grptime, grppre, grplist, annmsg, postdest, dring, needsconf, remotealert, toolate, ringing, pre_ring FROM findmefollow WHERE grpnum = '".str_replace("'", "''", $grpnum)."'","getRow",DB_FETCHMODE_ASSOC);
 
 	if ($check_astdb) {
 		if ($astman) {
@@ -272,6 +303,7 @@
 		} else {
 			fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
 		}
+			$astdb_ddial   = $astman->database_get("AMPUSER",$grpnum."/followme/ddial");                                     
 		// If the values are different then use what is in astdb as it may have been changed.
 		//
 		$changed=0;
@@ -301,10 +333,22 @@
 			$changed=1;
 		}
 
+		// Not in sql so no sanity check needed
+		//
+		if (trim($astdb_ddial) == 'EXTENSION') {
+			$ddial = 'CHECKED';
+		} elseif (trim($astdb_ddial) == 'DIRECT') {
+			$ddial = '';
+		} else {
+			//Bogus value, should not get here but treat as disabled
+			$ddial = '';
+		}
+		$results['ddial'] = $ddial;
+
 		if ($changed) {
 			$sql = "UPDATE findmefollow SET grptime = '".$results['grptime']."', grplist = '".
 				str_replace("'", "''", trim($results['grplist']))."', pre_ring = '".$results['pre_ring'].
-				"', needsconf = '".$results['needsconf']."' WHERE grpnum = $grpnum LIMIT 1";
+				"', needsconf = '".$results['needsconf']."' WHERE grpnum = '".str_replace("'", "''", $grpnum)."' LIMIT 1";
 			$sql_results = sql($sql);
 		}
 	} // if check_astdb

Modified: freepbx-modules/trunk/modules/findmefollow/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/findmefollow/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/findmefollow/install.php (original)
+++ freepbx-modules/trunk/modules/findmefollow/install.php Mon Apr  7 13:18:05 2008
@@ -9,7 +9,7 @@
 	// add new field
     $sql = "ALTER TABLE findmefollow ADD pre_ring SMALLINT( 6 ) NOT NULL DEFAULT 0 ;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 }
 // Version 2.0 upgrade. Yeah. 2.0 baby! 
 $sql = "SELECT remotealert FROM findmefollow";
@@ -18,15 +18,15 @@
 	// add new field
     $sql = "ALTER TABLE findmefollow ADD remotealert VARCHAR( 80 ) NULL ;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 
     $sql = "ALTER TABLE findmefollow ADD needsconf VARCHAR( 10 ) NULL ;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 
     $sql = "ALTER TABLE findmefollow ADD toolate VARCHAR( 80 ) NULL ;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 }
 // Version 2.1 upgrade. Add support for ${DIALOPTS} override, playing MOH
 $sql = "SELECT ringing FROM findmefollow";
@@ -35,10 +35,29 @@
 	// add new field
     $sql = "ALTER TABLE findmefollow ADD ringing VARCHAR( 80 ) NULL ;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 }
 // increase size for older installs
 $db->query("ALTER TABLE findmefollow CHANGE dring dring VARCHAR( 255 ) NULL");
+
+$results = array();
+$sql = "SELECT grpnum, postdest FROM findmefollow";
+$results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
+if (!DB::IsError($results)) { // error - table must not be there
+	foreach ($results as $result) {
+		$old_dest  = $result['postdest'];
+		$grpnum    = $result['grpnum'];
+
+		$new_dest = merge_ext_followme(trim($old_dest));
+		if ($new_dest != $old_dest) {
+			$sql = "UPDATE findmefollow SET postdest = '$new_dest' WHERE grpnum = '$grpnum'  AND postdest = '$old_dest'";
+			$results = $db->query($sql);
+			if(DB::IsError($results)) {
+				die_freepbx($results->getMessage());
+			}
+		}
+	}
+}
 
 // this function builds the AMPUSER/<grpnum>/followme tree for each user who has a group number
 // it's purpose is to convert after an upgrade
@@ -63,9 +82,20 @@
 		$astman->database_put("AMPUSER",$grpnum."/followme/grplist",isset($grplist)?$grplist:'');
 		$confvalue = ($needsconf == 'CHECKED')?'ENABLED':'DISABLED';
 		$astman->database_put("AMPUSER",$grpnum."/followme/grpconf",isset($needsconf)?$confvalue:'');
+		$ddial = $astman->database_get("AMPUSER",$grpnum."/followme/ddial");                                     
+		$ddial = ($ddial == 'EXTENSION' || $ddial == 'DIRECT')?$ddial:'DIRECT';
+		$astman->database_put("AMPUSER",$grpnum."/followme/ddial",$ddial);
 	}	
 } else {
 	echo _("Cannot connect to Asterisk Manager with ").$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"];
 }
 
+// Version 2.4.13 change (#1961)
+//
+$results = $db->query("ALTER TABLE `findmefollow` CHANGE `grpnum` `grpnum` VARCHAR( 20 ) NOT NULL");
+if(DB::IsError($results)) {
+	echo $results->getMessage();
+	return false;
+}
+
 ?>

Modified: freepbx-modules/trunk/modules/findmefollow/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/findmefollow/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/findmefollow/install.sql (original)
+++ freepbx-modules/trunk/modules/findmefollow/install.sql Mon Apr  7 13:18:05 2008
@@ -1,3 +1,3 @@
 
-CREATE TABLE IF NOT EXISTS `findmefollow` ( `grpnum` BIGINT( 11 ) NOT NULL , `strategy` VARCHAR( 50 ) NOT NULL , `grptime` SMALLINT NOT NULL , `grppre` VARCHAR( 100 ) NULL , `grplist` VARCHAR( 255 ) NOT NULL , `annmsg` VARCHAR( 255 ) NULL , `postdest` VARCHAR( 255 ) NULL , `dring` VARCHAR ( 255 ) NULL , remotealert VARCHAR ( 80 ), needsconf VARCHAR ( 10 ), toolate VARCHAR ( 80 ), pre_ring SMALLINT NOT NULL DEFAULT 0, PRIMARY KEY  (`grpnum`) ) TYPE = MYISAM ;
+CREATE TABLE IF NOT EXISTS `findmefollow` ( `grpnum` VARCHAR( 20 ) NOT NULL , `strategy` VARCHAR( 50 ) NOT NULL , `grptime` SMALLINT NOT NULL , `grppre` VARCHAR( 100 ) NULL , `grplist` VARCHAR( 255 ) NOT NULL , `annmsg` VARCHAR( 255 ) NULL , `postdest` VARCHAR( 255 ) NULL , `dring` VARCHAR ( 255 ) NULL , remotealert VARCHAR ( 80 ), needsconf VARCHAR ( 10 ), toolate VARCHAR ( 80 ), pre_ring SMALLINT NOT NULL DEFAULT 0, PRIMARY KEY  (`grpnum`) ) TYPE = MYISAM ;
 

Modified: freepbx-modules/trunk/modules/findmefollow/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/findmefollow/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/findmefollow/module.xml (original)
+++ freepbx-modules/trunk/modules/findmefollow/module.xml Mon Apr  7 13:18:05 2008
@@ -1,14 +1,20 @@
 <module>
 	<rawname>findmefollow</rawname>
 	<name>Follow Me</name>
-	<version>2.4.10.2</version>
+	<version>2.4.13.2</version>
 	<changelog>
-		*2.4.10.2* #2057 don't strip CID prefix if no prefix is being added
-		*2.4.10.1* #2002 IF() statement can't handle : in the string and can't escape them anyhow
-		*2.4.10* Fixed bug where nested CID prefixes ends up removing part of the valid CID info
-		*2.4.9.1* Fixed ALERT_INFO bug, if previously set it should not set - it was clearing it
-		*2.4.9* Add he_IL translation
-		*2.4.8* never allow extension to include itself as nnn# and create infinite loop
+		*2.4.13.2* #2193 moh path hardcoded
+		*2.4.13.1* bump for rc1
+		*2.4.13* added xml attribute needsenginedb, #1961 enabled to work with extension numbers leading with 0s
+		*2.4.12.3* #2057 don't strip CID prefix if no prefix is being added
+		*2.4.12.2* merge findmefollow/core extension destinations if any, and remove findmefollow destinations as a destination since they are handled by core
+		*2.4.12.1* #2002 IF() statement can't handle : in the string and can't escape them anyhow
+		*2.4.12* Fixed bug where nested CID prefixes ends up removing part of the valid CID info
+		*2.4.11.1* Fixed ALERT_INFO bug, if previously set it should not set - it was clearing it
+		*2.4.11* added option to have follow-me always be used in place of extension, or only when explicitly used as a destination, useful in conjunction with VmX
+		*2.4.10* introduction of firstavailable firstnotonphone strategy that only rings one extension and optionally skips callwaiting REQUIRE CORE r3652
+		*2.4.9* never allow extension to include itself as nnn# and create infinite loop
+		*2.4.8* introduction of ringallv2 strategy that eliminates the double ring of the primary ext, REQUIRE CORE r3406
 		*2.4.7* Changed to not set alertinfo value if already set from before hitting followme
 		*2.4.6* Added BLKVM DB tree to fix inability to transfer a received call to another user, and make NODEST stuff work overall
 		*2.4.5* Modified NODEST stuff to improve some cases where it was still failing, and improve '#' transfer scenarios
@@ -34,9 +40,8 @@
 		Much like a ring group, but works on individual extensions. When someone calls the extension, it can be setup to ring for a number of seconds before trying to ring other extensions and/or external numbers, or to ring all at once, or in other various 'hunt' configurations. Most commonly used to ring someone's cell phone if they don't answer their extension.
 	</description>
 	<menuitems>
-		<findmefollow>Follow Me</findmefollow>
+		<findmefollow needsenginedb="yes">Follow Me</findmefollow>
 	</menuitems>
-	<location>release/2.2/findmefollow-2.4.10.1.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-FollowMe</info>
-	<md5sum>166dff4df6a12cbcd79c7a4e6157b5ed</md5sum>
+	<location>release/2.3/findmefollow-2.4.13.1.tgz</location>
+	<md5sum>2ce3986fa50e65b41298ef746fb38934</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/findmefollow/page.findmefollow.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/findmefollow/page.findmefollow.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/findmefollow/page.findmefollow.php (original)
+++ freepbx-modules/trunk/modules/findmefollow/page.findmefollow.php Mon Apr  7 13:18:05 2008
@@ -27,6 +27,7 @@
 isset($_REQUEST['toolate'])?$toolate = $_REQUEST['toolate']:$toolate='';
 isset($_REQUEST['ringing'])?$ringing = $_REQUEST['ringing']:$ringing='';
 isset($_REQUEST['pre_ring'])?$pre_ring = $_REQUEST['pre_ring']:$pre_ring='0';
+isset($_REQUEST['ddial'])?$ddial = $_REQUEST['ddial']:$ddial='';
 
 
 if (isset($_REQUEST['goto0']) && isset($_REQUEST[$_REQUEST['goto0']."0"])) {
@@ -69,7 +70,7 @@
 	} else {
 		//add group
 		if ($action == 'addGRP') {
-			findmefollow_add($account,$strategy,$grptime,implode("-",$grplist),$goto,$grppre,$annmsg,$dring,$needsconf,$remotealert,$toolate,$ringing,$pre_ring);
+			findmefollow_add($account,$strategy,$grptime,implode("-",$grplist),$goto,$grppre,$annmsg,$dring,$needsconf,$remotealert,$toolate,$ringing,$pre_ring,$ddial);
 
 			needreload();
 			redirect_standard();
@@ -85,7 +86,7 @@
 		//edit group - just delete and then re-add the extension
 		if ($action == 'edtGRP') {
 			findmefollow_del($account);	
-			findmefollow_add($account,$strategy,$grptime,implode("-",$grplist),$goto,$grppre,$annmsg,$dring,$needsconf,$remotealert,$toolate,$ringing,$pre_ring);
+			findmefollow_add($account,$strategy,$grptime,implode("-",$grplist),$goto,$grppre,$annmsg,$dring,$needsconf,$remotealert,$toolate,$ringing,$pre_ring,$ddial);
 
 			needreload();
 			redirect_standard('extdisplay');
@@ -123,19 +124,21 @@
 	if ($extdisplay) {
 		// We need to populate grplist with the existing extension list.
 		$thisgrp = findmefollow_get(ltrim($extdisplay,'GRP-'), 1);
-		$grpliststr = $thisgrp['grplist'];
+		$grpliststr = isset($thisgrp['grplist']) ? $thisgrp['grplist'] : '';
 		$grplist = explode("-", $grpliststr);
-		$strategy = $thisgrp['strategy'];
-		$grppre = $thisgrp['grppre'];
-		$grptime = $thisgrp['grptime'];
-		$goto = $thisgrp['postdest'];
-		$annmsg = $thisgrp['annmsg'];
-		$dring = $thisgrp['dring'];
-		$remotealert = $thisgrp['remotealert'];
-		$needsconf = $thisgrp['needsconf'];
-		$toolate = $thisgrp['toolate'];
-		$ringing = $thisgrp['ringing'];
-		$pre_ring = $thisgrp['pre_ring'];
+
+		$strategy    = isset($thisgrp['strategy'])    ? $thisgrp['strategy']    : '';
+		$grppre      = isset($thisgrp['grppre'])      ? $thisgrp['grppre']      : '';
+		$grptime     = isset($thisgrp['grptime'])     ? $thisgrp['grptime']     : '';
+		$goto        = isset($thisgrp['postdest'])    ? $thisgrp['postdest']    : '';
+		$annmsg      = isset($thisgrp['annmsg'])      ? $thisgrp['annmsg']      : '';
+		$dring       = isset($thisgrp['dring'])       ? $thisgrp['dring']       : '';
+		$remotealert = isset($thisgrp['remotealert']) ? $thisgrp['remotealert'] : '';
+		$needsconf   = isset($thisgrp['needsconf'])   ? $thisgrp['needsconf']   : '';
+		$toolate     = isset($thisgrp['toolate'])     ? $thisgrp['toolate']     : '';
+		$ringing     = isset($thisgrp['ringing'])     ? $thisgrp['ringing']     : '';
+		$pre_ring    = isset($thisgrp['pre_ring'])    ? $thisgrp['pre_ring']    : '';
+		$ddial       = isset($thisgrp['ddial'])       ? $thisgrp['ddial']       : '';
 		unset($grpliststr);
 		unset($thisgrp);
 		
@@ -180,6 +183,11 @@
 				<td><a href="#" class="info"><?php echo _("group number")?>:<span><?php echo _("The number users will dial to ring extensions in this ring group")?></span></a></td>
 				<td><input size="5" type="text" name="account" value="<?php  echo $gresult[0] + 1; ?>"></td>
 <?php 		} ?>
+			</tr>
+
+			<tr>
+				<td><a href="#" class="info"><?php echo _("Disable as Default")?><span><?php echo _('By default (not checked) any call to this extension will go to this FollowMe instead, including directory calls by name from IVRs. If checked, calls will go only to the extension.<BR>However, destinations that specify FollowMe will come here.<BR>Checking this box is often used in conjunction with VmX Locater, where you want a call to ring the extension, and then only if the caller chooses to find you do you want it to come here.')?></span></a>:</td>
+				<td><input type="checkbox" name="ddial" value="CHECKED" <?php echo $ddial ?>  /></td>
 			</tr>
 
 			<tr>
@@ -202,19 +210,22 @@
 
 
 			<tr>
-				<td> <a href="#" class="info"><?php echo _("ring strategy:")?>
+				<td> <a href="#" class="info"><?php echo _("Ring Strategy:")?>
 				<span>
+					<b><?php echo _("ringallv2")?></b>:  <?php echo _("ring primary extension for initial ring time followed by all additional extensions until one answers")?><br>
 					<b><?php echo _("ringall")?></b>:  <?php echo _("ring all available channels until one answers (default)")?><br>
 					<b><?php echo _("hunt")?></b>: <?php echo _("take turns ringing each available extension")?><br>
 					<b><?php echo _("memoryhunt")?></b>: <?php echo _("ring first extension in the list, then ring the 1st and 2nd extension, then ring 1st 2nd and 3rd extension in the list.... etc.")?><br>
-                                        <b><?php echo _("*-prim")?></b>:  <?php echo _("these modes act as described above. However, if the primary extension (first in list) is occupied, the other extensions will not be rung. If the primary is freepbx DND, it won't be run. If the primary is freepbx CF unconditional, then all will be rung")?><br>
+					<b><?php echo _("*-prim")?></b>:  <?php echo _("these modes act as described above. However, if the primary extension (first in list) is occupied, the other extensions will not be rung. If the primary is freepbx DND, it won't be run. If the primary is freepbx CF unconditional, then all will be rung")?><br>
+					<b><?php echo _("firstavailable")?></b>:  <?php echo _("ring only the first available channel")?><br>
+					<b><?php echo _("firstnotonphone")?></b>:  <?php echo _("ring only the first channel which is not offhook - ignore CW")?><br>
 				</span>
 				</a></td>
 				<td>
 					&nbsp;&nbsp;<select name="strategy"/>
 					<?php
 						$default = (isset($strategy) ? $strategy : 'ringall');
-                                                $items = array('ringall','ringall-prim','hunt','hunt-prim','memoryhunt','memoryhunt-prim');
+                                                $items = array('ringallv2','ringallv2-prim','ringall','ringall-prim','hunt','hunt-prim','memoryhunt','memoryhunt-prim','firstavailable','firstnotonphone');
 						foreach ($items as $item) {
 							echo '<option value="'.$item.'" '.($default == $item ? 'SELECTED' : '').'>'._($item);
 						}
@@ -269,7 +280,7 @@
 	</tr>
 <?php } ?>
 			<tr>
-				<td valign="top"><a href="#" class="info"><?php echo _("extension list")?>:<span><br><?php echo _("List extensions to ring, one per line.<br><br>You can include an extension on a remote system, or an external number by suffixing a number with a pound (#).  ex:  2448089# would dial 2448089 on the appropriate trunk (see Outbound Routing).")?><br><br></span></a></td>
+				<td valign="top"><a href="#" class="info"><?php echo _("Follow-Me List")?>:<span><br><?php echo _("List extensions to ring, one per line.<br><br>You can include an extension on a remote system, or an external number by suffixing a number with a pound (#).  ex:  2448089# would dial 2448089 on the appropriate trunk (see Outbound Routing).")?><br><br></span></a></td>
 				<td valign="top">&nbsp;
 <?php
 		$rows = count($grplist)+1; 
@@ -284,18 +295,18 @@
 				</td>
 			</tr>
 			<tr>
-				<td><a href="#" class="info"><?php echo _("CID name prefix")?>:<span><?php echo _('You can optionally prefix the Caller ID name when ringing extensions in this group. ie: If you prefix with "Sales:", a call from John Doe would display as "Sales:John Doe" on the extensions that ring.')?></span></a></td>
+				<td><a href="#" class="info"><?php echo _("CID Name Prefix")?>:<span><?php echo _('You can optionally prefix the Caller ID name when ringing extensions in this group. ie: If you prefix with "Sales:", a call from John Doe would display as "Sales:John Doe" on the extensions that ring.')?></span></a></td>
 				<td><input size="4" type="text" name="grppre" value="<?php  echo $grppre ?>"></td>
 			</tr>
 
 
 			<tr>
-				<td><?php echo _("ring time (max 60 sec)")?>:</td>
+				<td><?php echo _("Ring Time (max 60 sec)")?>:</td>
 				<td><input size="4" type="text" name="grptime" value="<?php  echo $grptime?$grptime:20 ?>"></td>
 			</tr>
 <?php if(function_exists('recordings_list')) { //only include if recordings is enabled?>
 	<tr>
-		<td><a href="#" class="info"><?php echo _("announcement:")?><span><?php echo _("Message to be played to the caller before dialing this group.<br><br>To add additional recordings please use the \"System Recordings\" MENU to the left")?></span></a></td>
+		<td><a href="#" class="info"><?php echo _("Announcement:")?><span><?php echo _("Message to be played to the caller before dialing this group.<br><br>To add additional recordings please use the \"System Recordings\" MENU to the left")?></span></a></td>
 		<td>
 			&nbsp;&nbsp;<select name="annmsg"/>
 			<?php
@@ -313,7 +324,7 @@
 	</tr>
 <?php }	else { ?>
 	<tr>
-		<td><a href="#" class="info"><?php echo _("announcement:")?><span><?php echo _("Message to be played to the caller before dialing this group.<br><br>You must install and enable the \"Systems Recordings\" Module to edit this option")?></span></a></td>
+		<td><a href="#" class="info"><?php echo _("Announcement:")?><span><?php echo _("Message to be played to the caller before dialing this group.<br><br>You must install and enable the \"Systems Recordings\" Module to edit this option")?></span></a></td>
 		<td>
 			<?php
 				$default = (isset($annmsg) ? $annmsg : '');
@@ -327,7 +338,7 @@
 		<td>
 			&nbsp;&nbsp;<select name="ringing"/>
 			<?php
-				$tresults = music_list("/var/lib/asterisk/mohmp3");
+				$tresults = music_list($amp_conf['ASTVARLIBDIR']."/mohmp3");
 				$cur = (isset($ringing) ? $ringing : 'Ring');
 				echo '<option value="Ring">'._("Ring")."</option>";
 				if (isset($tresults[0])) {
@@ -363,12 +374,11 @@
 
 function checkGRP(theForm) {
 	var msgInvalidGrpNum = "<?php echo _('Invalid Group Number specified'); ?>";
-	var msgInvalidGrpNumStartWithZero = "<?php echo _('Group numbers with more than one digit cannot begin with 0'); ?>";
 	var msgInvalidExtList = "<?php echo _('Please enter an extension list.'); ?>";
 	var msgInvalidGrpPrefix = "<?php echo _('Invalid prefix. Valid characters: a-z A-Z 0-9 : _ -'); ?>";
 	var msgInvalidTime = "<?php echo _('Invalid time specified'); ?>";
 	var msgInvalidGrpTimeRange = "<?php echo _('Time must be between 1 and 60 seconds'); ?>";
-	var msgInvalidRingStrategy = "<?php echo _('You must choose ringall or ringall-prim ring strategy when using Confirm Calls'); ?>";
+	var msgInvalidRingStrategy = "<?php echo _('You must choose ringall, ringall-prim, ringallv2 or ringallv2-prim ring strategy when using Confirm Calls'); ?>";
 
 
 

Modified: freepbx-modules/trunk/modules/findmefollow/uninstall.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/findmefollow/uninstall.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/findmefollow/uninstall.php (original)
+++ freepbx-modules/trunk/modules/findmefollow/uninstall.php Mon Apr  7 13:18:05 2008
@@ -21,10 +21,7 @@
 if ($astman) {
 	foreach($userresults as $usr) {
 		extract($usr);
-		$astman->database_del("AMPUSER",$extension."/followme/prering");
-		$astman->database_del("AMPUSER",$extension."/followme/grptime");
-		$astman->database_del("AMPUSER",$extension."/followme/grplist");
-		$astman->database_del("AMPUSER",$extension."/followme/grpconf");
+		$astman->database_deltree("AMPUSER/".$grpnum."/followme");
 	}	
 } else {
 	echo _("Cannot connect to Asterisk Manager with ").$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"];

Modified: freepbx-modules/trunk/modules/gabcast/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/gabcast/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/gabcast/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/gabcast/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -132,7 +132,8 @@
 
         $id = "app-gabcast"; // The context to be included
 		$ext->addInclude('from-internal-additional', $id);
-		$ext->add($id, $c, '', new ext_goto('1','${CALLERID(num)}','gabcast'));
+		$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
+		$ext->add($id, $c, '', new ext_goto('1','${AMPUSER}','gabcast'));
 /*		
         $ext->add($id, $c, '', new ext_macro('user-callerid'));
         $ext->add($id, $c, '', new ext_noop('Checking for ${CALLERID(num)}'));

Modified: freepbx-modules/trunk/modules/gabcast/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/gabcast/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/gabcast/module.xml (original)
+++ freepbx-modules/trunk/modules/gabcast/module.xml Mon Apr  7 13:18:05 2008
@@ -1,17 +1,19 @@
 <module>
 	<rawname>gabcast</rawname>
 	<name>Gabcast</name>
-	<version>1.2.3</version>
+	<version>1.2.5.1</version>
 	<type>tool</type>
 	<category>Third Party Addon</category>
 	<menuitems>
 		<gabcast>Gabcast</gabcast>
 	</menuitems>
 	<changelog>
+		*1.2.5.1* bump for rc1
+		*1.2.5* #2070 fix proper use of script tags
+	  *1.2.4* changed ${CALLERID(number)} to ${AMPUSER} to accomodate CID number masquerading
 		*1.2.3* Add he_IL translation
 		*1.2.2* Fix issue where you were unable to add a channel 
 	</changelog>
-	<location>release/2.2/gabcast-1.2.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-gabcast</info>
-	<md5sum>c3d15a633d06425ccbd1e4064aed4995</md5sum>
+	<location>release/2.3/gabcast-1.2.5.tgz</location>
+	<md5sum>76c23ec8d6cb80e3bcde20e1390a67fb</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/gabcast/page.gabcast.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/gabcast/page.gabcast.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/gabcast/page.gabcast.php (original)
+++ freepbx-modules/trunk/modules/gabcast/page.gabcast.php Mon Apr  7 13:18:05 2008
@@ -78,7 +78,7 @@
 <div style=;margin-top:20px;>
 	<?php echo gabcast_player();?>
 </div>
-<?
+<?php
 }
 
 function gabcast_show($xtn, $type, $iam) {

Modified: freepbx-modules/trunk/modules/infoservices/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/infoservices/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/infoservices/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/infoservices/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -32,6 +32,8 @@
 	global $ext;
 	global $db;
 
+	$oxtn = $db->getOne("SELECT value from globals where variable='OPERATOR_XTN'");	//this needs to be here!
+
 	$id = "app-directory"; // The context to be included. This must be unique.
 
 	// Start creating the dialplan
@@ -39,10 +41,9 @@
 	// Build the context
 	$ext->add($id, $c, '', new ext_answer(''));
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,1,Wait(1)
-	$ext->add($id, $c, '', new ext_agi('directory,${DIR-CONTEXT},from-did-direct,${DIRECTORY:0:1}${DIRECTORY_OPTS}'.(!empty($oxtn) ? 'o' : '') )); // AGI
+	$ext->add($id, $c, '', new ext_agi('directory,${DIR-CONTEXT},from-did-direct,${DIRECTORY:0:1}${DIRECTORY_OPTS}'.($oxtn != '' ? 'o' : '') ));
 	$ext->add($id, $c, '', new ext_playback('vm-goodbye')); // $cmd,n,Playback(vm-goodbye)
 	$ext->add($id, $c, '', new ext_hangup('')); // hangup
-	$oxtn = $db->getOne("SELECT value from globals where variable='OPERATOR_XTN'");
 	if ($oxtn != '') {
 		$ext->add($id, 'o', '', new ext_goto('from-internal,${OPERATOR_XTN},1')); 
 	} else {
@@ -63,11 +64,11 @@
 	// I just reset these for ease of copying and pasting. 
 	$id = 'app-calltrace-perform';
 	$c = 's';
-	$ext->add($id, $c, '', new ext_macro('user-callerid')); 
 	$ext->add($id, $c, '', new ext_answer(''));
 	$ext->add($id, $c, '', new ext_wait('1'));
+	$ext->add($id, $c, '', new ext_macro('user-callerid')); 
 	$ext->add($id, $c, '', new ext_playback('info-about-last-call&telephone-number'));
-	$ext->add($id, $c, '', new ext_setvar('lastcaller', '${DB(CALLTRACE/${CALLERID(number)})}'));
+	$ext->add($id, $c, '', new ext_setvar('lastcaller', '${DB(CALLTRACE/${AMPUSER})}'));
 	$ext->add($id, $c, '', new ext_gotoif('$[ $[ "${lastcaller}" = "" ] | $[ "${lastcaller}" = "unknown" ] ]', 'noinfo'));
 	$ext->add($id, $c, '', new ext_saydigits('${lastcaller}'));
 	$ext->add($id, $c, '', new ext_setvar('TIMEOUT(digit)', '3'));
@@ -77,6 +78,8 @@
 	$ext->add($id, $c, 'noinfo', new ext_playback('from-unknown-caller'));
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); 
 	$ext->add($id, $c, 'fin', new ext_noop('Waiting for input'));
+	$ext->add($id, $c, '', new ext_waitexten(60));
+	$ext->add($id, $c, '', new ext_Playback('sorry-youre-having-problems&goodbye'));
 	$ext->add($id, '1', '', new ext_goto('1', '${lastcaller}', 'from-internal'));
 	$ext->add($id, 'i', '', new ext_playback('vm-goodbye')); 
 	$ext->add($id, 'i', '', new ext_macro('hangupcall')); 
@@ -145,7 +148,7 @@
 	$ext->add($id, $c, '', new ext_playback('extension'));
 	$ext->add($id, $c, '', new ext_playback('number'));
 	$ext->add($id, $c, '', new ext_playback('is'));
-	$ext->add($id, $c, '', new ext_saydigits('${CALLERID(number)}'));
+	$ext->add($id, $c, '', new ext_saydigits('${AMPUSER}'));
 	$ext->add($id, $c, '', new ext_wait('2')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_hangup(''));
 }

Modified: freepbx-modules/trunk/modules/infoservices/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/infoservices/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/infoservices/module.xml (original)
+++ freepbx-modules/trunk/modules/infoservices/module.xml Mon Apr  7 13:18:05 2008
@@ -1,16 +1,22 @@
 <module>
 	<rawname>infoservices</rawname>
 	<name>Info Services</name>
-	<version>1.3.3</version>
+	<version>1.3.5.3</version>
+	<candisable>no</candisable>
+	<canuninstall>no</canuninstall>
 	<type>setup</type>
-	<category>Provides a Feature Code</category>
+	<category>Internal Options &amp; Configuration</category>
 	<description>Provides a number of applications accessable by feature codes: company directory, call trace (last call information), echo test, speaking clock, and speak current extension number.</description>
 	<changelog>
-		1.3.3: Fixed SpeakExtension - replaced depricated ${CALLERID} variable
-		1.3.2: Fixed SpeakExtension - add macro-user-callerid
-		1.3.1: Improved accuracy of speaking clock
+		*1.3.5.3* #2731 fix press 0 for operator in directory
+		*1.3.5.2* changed categories
+		*1.3.5.1* bump for rc1
+		*1.3.5* #2145 add waitexten while waiting for user input, and make uninstallable
+		*1.3.4* changed ${CALLERID(number)} to ${AMPUSER} to accomodate CID number masquerading
+		*1.3.3* Fixed SpeakExtension - replaced depricated ${CALLERID} variable
+		*1.3.2* Fixed SpeakExtension - add macro-user-callerid
+		*1.3.1* Improved accuracy of speaking clock
 	</changelog>
-	<location>release/2.2/infoservices-1.3.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Features</info>
-	<md5sum>fc56917b226ccfb87fe546fcc9cae658</md5sum>
+	<location>release/2.3/infoservices-1.3.5.1.tgz</location>
+	<md5sum>428df7844e8efbe6114920d39fbe5859</md5sum>
 </module>

Added: freepbx-modules/trunk/modules/inventorydb/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/inventorydb/install.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/inventorydb/install.php (added)
+++ freepbx-modules/trunk/modules/inventorydb/install.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,35 @@
+<?php
+
+global $db;
+global $amp_conf;
+
+$autoincrement = ($amp_conf["AMPDBENGINE"] == "sqlite3") ? "AUTOINCREMENT":"AUTO_INCREMENT";
+
+$sql = "CREATE TABLE IF NOT EXISTS inventorydb (
+        id INTEGER NOT NULL PRIMARY KEY $autoincrement,
+	empnum varchar(10) null,
+	empname varchar(20) NOT NULL,
+	building varchar(150) NULL,
+	floor varchar(10) NULL,
+	room varchar(10) NULL,
+	section varchar(6) NULL,
+	cubicle varchar(6) NULL,
+	desk varchar(6) NULL,
+	exten  varchar(8) NULL,
+	phusername varchar(10) NULL, 
+	phpassword varchar(10) NULL,
+	mac varchar(18) NULL,
+	serial varchar(20) NULL, 
+	device varchar(20) NULL, 
+	distdate varchar(10) NULL, 
+	ip varchar(14) NULL, 
+	pbxbox varchar(20) NULL,
+	extrainfo varchar(256) NULL
+);";
+
+$check = $db->query($sql);
+if(DB::IsError($check)) {
+        die_freepbx("Can not create `inventorydb` table\n");
+}
+
+?>

Modified: freepbx-modules/trunk/modules/inventorydb/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/inventorydb/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/inventorydb/install.sql (original)
+++ freepbx-modules/trunk/modules/inventorydb/install.sql Mon Apr  7 13:18:05 2008
@@ -1,21 +1,1 @@
-CREATE TABLE IF NOT EXISTS inventorydb (
- id int UNIQUE AUTO_INCREMENT,
- empnum varchar(10) null,
- empname varchar(20) not null,
- building varchar(150) null,
- floor varchar(10) null,
- room varchar(10) null,
- section varchar(6) null,
- cubicle varchar(6) null,
- desk varchar(6) null,
- exten  varchar(8) null,
- phusername varchar(10) null, 
- phpassword varchar(10) null,
- mac varchar(18) null,
- serial varchar(20) null, 
- device varchar(20) null, 
- distdate varchar(10) null, 
- ip varchar(14) null, 
- pbxbox varchar(20) null,
- extrainfo varchar(256) null
- );
+# see install.php

Modified: freepbx-modules/trunk/modules/inventorydb/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/inventorydb/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/inventorydb/module.xml (original)
+++ freepbx-modules/trunk/modules/inventorydb/module.xml Mon Apr  7 13:18:05 2008
@@ -1,17 +1,17 @@
 <module>
 	<rawname>inventorydb</rawname>
 	<name>Inventory</name>
-	<version>1.0.3</version>
+	<version>1.1.0</version>
 	<type>tool</type>
 	<category>Third Party Addon</category>
 	<menuitems>
 		<inventorydb>Inventory</inventorydb>
 	</menuitems>
 	<changelog>
+		*1.1.0* Added SQLite3 support. Fixes ticket:1783, bump for rc1
 		*1.0.3* Add he_IL translation
 	</changelog>
-	<location>release/2.2/inventorydb-1.0.2.tgz</location>
-	<md5sum>cc81eee30f026a2234bde90d7c2e4989</md5sum>
-	<info>http://freepbx.org/wiki/inventorydb</info>
+	<location>release/2.3/inventorydb-1.0.3.tgz</location>
+	<md5sum>c91eeb1f8c96e0734df8b34c35e453b2</md5sum>
 </module>
 

Modified: freepbx-modules/trunk/modules/inventorydb/page.inventorydb.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/inventorydb/page.inventorydb.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/inventorydb/page.inventorydb.php (original)
+++ freepbx-modules/trunk/modules/inventorydb/page.inventorydb.php Mon Apr  7 13:18:05 2008
@@ -16,7 +16,7 @@
 
 $display = isset($_REQUEST['display'])?$_REQUEST['display']:'inventorydb';
 $extdisplay = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:'';
-$type = isset($_REQUEST['type'])?$_REQUEST['type']:'setup';
+$type = isset($_REQUEST['type'])?$_REQUEST['type']:'tool';
 $action = isset($_REQUEST['action'])?$_REQUEST['action']:'';
 $empnum = isset($_REQUEST['empnum'])?$_REQUEST['empnum']:'';
 $empname = isset($_REQUEST['empname'])?$_REQUEST['empname']:'';
@@ -145,6 +145,7 @@
 echo ($action=="" ? "add" : $action);
 echo "\">\n";
 echo "<input type=hidden name=display value=\"inventorydb\">";
+echo "<input type=hidden name=type value=\"tool\">";
 
 echo "<table>";
 
@@ -176,7 +177,7 @@
 echo "<a href=\"#\" class=\"info\">Building Located\n";
 echo "<span>Building where the phone is located</span></a>\n";
 echo "</td><td>\n";
-echo "<input name=\"building\" value=\"$building\"\n";
+echo "<input name=\"building\" value=\"$building\">\n";
 echo "</td></tr>\n";
 
 //floor

Modified: freepbx-modules/trunk/modules/inventorydb/uninstall.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/inventorydb/uninstall.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/inventorydb/uninstall.sql (original)
+++ freepbx-modules/trunk/modules/inventorydb/uninstall.sql Mon Apr  7 13:18:05 2008
@@ -1,1 +1,1 @@
-DROP TABLE inventorydb;
+DROP TABLE `inventorydb`;

Modified: freepbx-modules/trunk/modules/ivr/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/ivr/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/ivr/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/ivr/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -1,5 +1,5 @@
 <?php
- /* $Id: functions.inc.php 4030 2007-06-09 04:18:36Z p_lindheimer $ */
+ /* $Id: functions.inc.php 5714 2008-02-19 04:38:58Z p_lindheimer $ */
 
 
 function ivr_init() {
@@ -142,6 +142,8 @@
 					if (!empty($details['enable_directory'])) {
 						$ext->addInclude($id,'app-directory');
 						$dir = featurecodes_getFeatureCode('infoservices', 'directory');
+						$ext->add($id, '#' ,'', new ext_dbdel('${BLKVM_OVERRIDE}'));
+						$ext->add($id, '#' ,'', new ext_setvar('__NODEST', ''));
 						$ext->add($id, '#', '', new ext_goto("app-directory,$dir,1"));
 					}
 
@@ -158,10 +160,7 @@
 					if ($announcement != '') {
 						$ext->add($id, 's', '', new ext_background($announcement));
 					}
-					/* TODO: once depends functionality gets fixed in core this should be put back
 					$ext->add($id, 's', '', new ext_waitexten());
-					*/
-					$ext->add($id, 's', '', new extension('WaitExten()'));
 					$ext->add($id, 'hang', '', new ext_playback('vm-goodbye'));
 					$ext->add($id, 'hang', '', new ext_hangup(''));
 

Modified: freepbx-modules/trunk/modules/ivr/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/ivr/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/ivr/install.php (original)
+++ freepbx-modules/trunk/modules/ivr/install.php Mon Apr  7 13:18:05 2008
@@ -21,7 +21,7 @@
     $sql = 'ALTER TABLE ivr ADD COLUMN dircontext VARCHAR ( 50 ) DEFAULT "default"';
     $result = $db->query($sql);
     if(DB::IsError($result)) {
-            die($result->getDebugInfo());
+            die_freepbx($result->getDebugInfo());
     }
 }
 
@@ -30,7 +30,7 @@
 	$sql = "ALTER TABLE ivr CHANGE COLUMN announcement announcement VARCHAR ( 255 )";
     $result = $db->query($sql);
     if(DB::IsError($result)) {
-            die($result->getDebugInfo());
+            die_freepbx($result->getDebugInfo());
     } else {
     	// Change existing records
     	//echo "<p>Updating existing records</p>";
@@ -47,7 +47,7 @@
     				$sql = "UPDATE ivr SET announcement = '".str_replace("'", "''", $filename)."' WHERE announcement = '$recid'";
 				    $upcheck = $db->query($sql);
 				    if(DB::IsError($upcheck))
-				            die($upcheck->getDebugInfo());    				
+				            die_freepbx($upcheck->getDebugInfo());    				
     			}
     		}
     	}
@@ -61,7 +61,28 @@
 	// add new field
     $sql = "ALTER TABLE ivr_dests ADD ivr_ret TINYINT(1) NOT NULL DEFAULT 0;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 }
 
+$results = array();
+$sql = "SELECT ivr_id, selection, dest FROM ivr_dests";
+$results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
+if (!DB::IsError($results)) { // error - table must not be there
+	foreach ($results as $result) {
+		$old_dest  = $result['dest'];
+		$ivr_id    = $result['ivr_id'];
+		$selection = $result['selection'];
+
+		$new_dest = merge_ext_followme(trim($old_dest));
+		if ($new_dest != $old_dest) {
+			$sql = "UPDATE ivr_dests SET dest = '$new_dest' WHERE ivr_id = $ivr_id AND selection = '$selection' AND dest = '$old_dest'";
+			$results = $db->query($sql);
+			if(DB::IsError($results)) {
+				die_freepbx($results->getMessage());
+			}
+		}
+	}
+}
+
+
 ?>

Modified: freepbx-modules/trunk/modules/ivr/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/ivr/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/ivr/module.xml (original)
+++ freepbx-modules/trunk/modules/ivr/module.xml Mon Apr  7 13:18:05 2008
@@ -1,14 +1,18 @@
 <module>
 	<rawname>ivr</rawname>
 	<name>IVR</name>
-	<version>2.5.15</version>
+	<version>2.5.15.2</version>
 	<type>setup</type>
 	<category>Inbound Call Control</category>
 	<description>
 		Creates Digital Receptionist (aka Auto-Attendant, aka Interactive Voice Response) menus. These can be used to send callers to different locations (eg, "Press 1 for sales") and/or allow direct-dialing of extension numbers. 
 	</description>
 	<changelog>
-		*2.5.15* add class to define waitexten and removed the dependency on 2.2.2 - since 2.2.2 dependency checking is broken
+		*2.5.15.2* #2687 breakout from Queue to Company Directory blocks voicemail
+		*2.5.15.1* bump for rc1
+		*2.5.15* bump version to be higher than 2.2 branch
+		*2.5.14.2* merge findmefollow/core extension destinations if any
+		*2.5.14.1* removed depends on 2.2.2 - classes are in all version of 2.3
 		*2.5.14* add waitexten to 2.2
 		*2.5.13.1* make sure t ext getting put in (for some reason it wasn't always, this shoudl fix it)
 		*2.5.13* #1871 't' extension not being created by default fixed
@@ -29,7 +33,6 @@
 	<menuitems>
 		<ivr>IVR</ivr>
 	</menuitems>
-	<location>release/2.2/ivr-2.5.14.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-IVR</info>
-	<md5sum>538a2bd521419cfa5be8e22e421aa558</md5sum>
+	<location>release/2.3/ivr-2.5.15.1.tgz</location>
+	<md5sum>c630e18e0145980f5bbd7f78247670a4</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/ivr/page.ivr.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/ivr/page.ivr.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/ivr/page.ivr.php (original)
+++ freepbx-modules/trunk/modules/ivr/page.ivr.php Mon Apr  7 13:18:05 2008
@@ -1,5 +1,5 @@
 <?php 
-/* $Id: page.ivr.php 3760 2007-02-09 22:44:33Z gregmac $ */
+/* $Id: page.ivr.php 3790 2007-02-16 18:52:53Z p_lindheimer $ */
 //Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
 //
 //This program is free software; you can redistribute it and/or

Modified: freepbx-modules/trunk/modules/logfiles/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/logfiles/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/logfiles/module.xml (original)
+++ freepbx-modules/trunk/modules/logfiles/module.xml Mon Apr  7 13:18:05 2008
@@ -1,13 +1,17 @@
 <module>
 	<rawname>logfiles</rawname>
 	<name>Asterisk Logfiles</name>
-	<version>1.0.1</version>
+	<version>1.1.1</version>
+	<changelog>
+		*1.1.1* bump for rc1
+		*1.1.0* #1442 remove access problem and have log display in same window
+		*1.0.2* #2070 fix proper use of script tags
+	</changelog>
 	<type>tool</type>
-	<category>Maintenance</category>
+	<category>Support</category>
 	<menuitems>
 		<logfiles>Asterisk Logfiles</logfiles>
 	</menuitems>
-	<location>release/logfiles-1.0.1.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-LogFiles</info>
-	<md5sum>67f2388f242071742e22247ed0ac0898</md5sum>
+	<location>release/2.3/logfiles-1.1.0.tgz</location>
+	<md5sum>bbfef694584fff2037fad03370fd684f</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/logfiles/page.logfiles.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/logfiles/page.logfiles.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/logfiles/page.logfiles.php (original)
+++ freepbx-modules/trunk/modules/logfiles/page.logfiles.php Mon Apr  7 13:18:05 2008
@@ -1,16 +1,33 @@
 <?php
 
-$display=$_REQUEST['display'];
+$display = $_REQUEST['display'];
+$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : 'tool';
+$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
 
-switch($display) {
+?>
+</div>
+<div class="content">
+<?php
+
+switch($action) {
+	case 'showlog':
+?>
+		<h2>
+			<?php echo sprintf(_('%s - last 2000 lines'),$amp_conf['ASTLOGDIR']."/full") ?>
+		</h2>
+		<a href="config.php?<?php echo "display=$display&type=$type&action=showlog"?>"><?php echo _("Redisplay Asterisk Full debug log (last 2000 lines)") ?></a><br>
+		<hr><br>
+		<?php
+		echo system ('tail --line=2000 '.$amp_conf['ASTLOGDIR'].'/full | sed -e "s/$/<br>/"'); 
+		break;
+
 	default:
-		
-		echo "<h2>Asterisk Log Files</h2>";
-        include 'logfiles.php';
-
+		echo "<h2>"._("Asterisk Log Files")."</h2>";
+?>
+				<a href="config.php?<?php echo "display=$display&type=$type&action=showlog"?>"><?php echo _("Display Asterisk Full debug log (last 2000 lines)") ?></a><br>
+				<br><br><br><br><br><br><br><br><br><br><br><br>
+<?php
     break;
-	    
 }
 ?>
-
 </div>

Added: freepbx-modules/trunk/modules/manager/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/manager/install.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/manager/install.php (added)
+++ freepbx-modules/trunk/modules/manager/install.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,23 @@
+<?php
+
+global $db;
+global $amp_conf;
+
+$autoincrement = (($amp_conf["AMPDBENGINE"] == "sqlite") || ($amp_conf["AMPDBENGINE"] == "sqlite3")) ? "AUTOINCREMENT":"AUTO_INCREMENT";
+
+$sql = "CREATE TABLE IF NOT EXISTS manager (
+	`manager_id` INTEGER NOT NULL PRIMARY KEY $autoincrement,
+	`name` VARCHAR( 15 ) NOT NULL ,
+	`secret` VARCHAR( 50 ) ,
+	`deny` VARCHAR( 255 ) ,
+	`permit` VARCHAR( 255 ) ,
+	`read` VARCHAR( 50 ) ,
+	`write` VARCHAR( 50 )
+)";
+
+$check = $db->query($sql);
+if (DB::IsError($check)) {
+	die_freepbx("Can not create `manager` table" .  $check->getMessage() .  "\n");
+}
+
+?>

Modified: freepbx-modules/trunk/modules/manager/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/manager/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/manager/install.sql (original)
+++ freepbx-modules/trunk/modules/manager/install.sql Mon Apr  7 13:18:05 2008
@@ -1,3 +1,3 @@
 
-CREATE TABLE IF NOT EXISTS `manager` ( `manager_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `name` VARCHAR( 15 ) NOT NULL , `secret` VARCHAR( 50 ) , `deny` VARCHAR( 255 ) , `permit` VARCHAR( 255 ) , `read` VARCHAR( 50 ) , `write` VARCHAR( 50 ) );
+-- left blank because of http://freepbx.org/trac/ticket/1277
 

Modified: freepbx-modules/trunk/modules/manager/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/manager/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/manager/module.xml (original)
+++ freepbx-modules/trunk/modules/manager/module.xml Mon Apr  7 13:18:05 2008
@@ -1,17 +1,18 @@
 <module>
 	<rawname>manager</rawname>
 	<name>Asterisk API</name>
-	<version>1.2</version>
+	<version>1.3.1</version>
 	<type>tool</type>
 	<category>System Administration</category>
 	<menuitems>
 		<manager>Asterisk API</manager>
 	</menuitems>
 	<changelog>
-	*1.2* Fix UI issues, and 'Array' message.
-	*1.1* First 2.2 release. Added he_IL support, fixed some warnings.
+		*1.3.1* bump for rc1
+		*1.3* Added SQLite3 support, fixes ticket 1776
+		*1.2* Fix UI issues, and 'Array' message.
+		*1.1* First 2.2 release. Added he_IL support, fixed some warnings.
 	</changelog>
-	<location>release/2.2/manager-1.1.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-ManagerAPI</info>
-	<md5sum>10c988b1df0744df34060711e2cdaf7c</md5sum>
+	<location>release/2.3/manager-1.3.tgz</location>
+	<md5sum>f6f2e9b7aaad3dd4e730a3893b8429c2</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/manager/uninstall.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/manager/uninstall.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/manager/uninstall.sql (original)
+++ freepbx-modules/trunk/modules/manager/uninstall.sql Mon Apr  7 13:18:05 2008
@@ -1,2 +1,2 @@
 
-DROP TABLE IF EXISTS manager;
+DROP TABLE IF EXISTS `manager`;

Modified: freepbx-modules/trunk/modules/miscapps/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscapps/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/miscapps/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/miscapps/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -47,7 +47,7 @@
 	$sql = "SELECT miscapps_id, description, dest FROM miscapps ORDER BY description ";
 	$results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
 	if(DB::IsError($results)) {
-		die($results->getMessage()."<br><br>Error selecting from miscapps");	
+		die_freepbx($results->getMessage()."<br><br>Error selecting from miscapps");	
 	}
 	
 	if ($get_ext) {
@@ -66,7 +66,7 @@
 	$sql = "SELECT miscapps_id, description, ext, dest FROM miscapps WHERE miscapps_id = ".addslashes($miscapps_id);
 	$row = $db->getRow($sql, DB_FETCHMODE_ASSOC);
 	if(DB::IsError($row)) {
-		die($row->getMessage()."<br><br>Error selecting row from miscapps");	
+		die_freepbx($row->getMessage()."<br><br>Error selecting row from miscapps");	
 	}
 	
 	// we want to get the ext from featurecodes
@@ -85,7 +85,7 @@
 		"'".addslashes($dest)."')";
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getMessage().$sql);
+		die_freepbx($result->getMessage().$sql);
 	}
 	//get id..
 	$miscapps_id = $db->getOne('SELECT LAST_INSERT_ID()');
@@ -104,7 +104,7 @@
 	$sql = "DELETE FROM miscapps WHERE miscapps_id = ".addslashes($miscapps_id);
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getMessage().$sql);
+		die_freepbx($result->getMessage().$sql);
 	}
 	
 	$fc = new featurecode('miscapps', 'miscapp_'.$miscapps_id);
@@ -120,7 +120,7 @@
 		"WHERE miscapps_id = ".addslashes($miscapps_id);
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getMessage().$sql);
+		die_freepbx($result->getMessage().$sql);
 	}
 	
 	$fc = new featurecode('miscapps', 'miscapp_'.$miscapps_id);

Added: freepbx-modules/trunk/modules/miscapps/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscapps/install.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/miscapps/install.php (added)
+++ freepbx-modules/trunk/modules/miscapps/install.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,37 @@
+<?php
+
+global $db;
+global $amp_conf;
+
+$autoincrement = (($amp_conf["AMPDBENGINE"] == "sqlite") || ($amp_conf["AMPDBENGINE"] == "sqlite3")) ? "AUTOINCREMENT":"AUTO_INCREMENT";
+$sql = "CREATE TABLE IF NOT EXISTS miscapps (
+	miscapps_id INTEGER NOT NULL PRIMARY KEY $autoincrement,
+	ext VARCHAR( 50 ) ,
+	description VARCHAR( 50 ) ,
+	dest VARCHAR( 255 )
+)";
+
+$check = $db->query($sql);
+if(DB::IsError($check)) {
+	die_freepbx("Can not create miscdests table\n");
+}
+$results = array();
+$sql = "SELECT miscapps_id, dest FROM miscapps";
+$results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
+if (!DB::IsError($results)) { // error - table must not be there
+	foreach ($results as $result) {
+		$old_dest    = $result['dest'];
+		$miscapps_id = $result['miscapps_id'];
+
+		$new_dest = merge_ext_followme(trim($old_dest));
+		if ($new_dest != $old_dest) {
+			$sql = "UPDATE miscapps SET dest = '$new_dest' WHERE miscapps_id = $miscapps_id  AND dest = '$old_dest'";
+			$results = $db->query($sql);
+			if(DB::IsError($results)) {
+				die_freepbx($results->getMessage());
+			}
+		}
+	}
+}
+
+?>

Modified: freepbx-modules/trunk/modules/miscapps/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscapps/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/miscapps/install.sql (original)
+++ freepbx-modules/trunk/modules/miscapps/install.sql Mon Apr  7 13:18:05 2008
@@ -1,6 +1,1 @@
-CREATE TABLE IF NOT EXISTS miscapps ( 
-	miscapps_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY , 
-	ext VARCHAR( 50 ) , 
-	description VARCHAR( 50 ) , 
-	dest VARCHAR( 255 ) 
-);
+-- empty file - see http://freepbx.org/trac/ticket/1277

Modified: freepbx-modules/trunk/modules/miscapps/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscapps/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/miscapps/module.xml (original)
+++ freepbx-modules/trunk/modules/miscapps/module.xml Mon Apr  7 13:18:05 2008
@@ -1,23 +1,27 @@
 <module>
 	<rawname>miscapps</rawname>
 	<name>Misc Applications</name>
-	<version>0.2.0.4</version>
+	<version>0.2.3.5</version>
 	<type>setup</type>
 	<category>Internal Options &amp; Configuration</category>
 	<description>
-		Adds the ability to create feature codes that can go to any freePBX destination (such as an IVR or queue)
+		Adds the ability to create feature codes that can go to any FreePBX destination (such as an IVR or queue)
 	</description>
-	<changelog>
-		*0.2.0.4* #2305 Feature Status broken
-		*0.2.0.3* #2177: removed apparently corrupted newline at end of file
-		*0.2.0.2* added proper uninstall, removes any feature codes and then table
-		*0.2.0.1* #1902 miscapp always sets/pulls default code now regardless of custom override in featurecodes
-		*0.2* Fix bug with adding new apps
-	</changelog>
 	<menuitems>
 		<miscapps>Misc Applications</miscapps>
 	</menuitems>
-	<location>release/2.2/miscapps-0.2.0.3.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-MiscApplications</info>
-	<md5sum>f8f5093433b3b3b3d0af9774c93b21f7</md5sum>
+	<changelog>
+		*0.2.3.5* #2305 Feature Status broken
+		*0.2.3.3* fixed some undefined variables, bump for rc1
+		*0.2.3.2* #2177: removed apparently corrupted newline at end of file
+		*0.2.3.1* added proper uninstall, removes any feature codes and then table
+		*0.2.3* #1902 miscapp always sets/pulls default code now regardless of custom override in featurecodes
+		*0.2.2* added SQLite3 support, fixes http://freepbx.org/trac/ticket/1775
+		*0.2.1.1* changed freePBX to FreePBX
+		*0.2.1* merge findmefollow/core extension destinations if any
+		*0.2* Fix bug with adding new apps
+		*0.1.1* Fixed publish location for trunk/2.3 repository
+	</changelog>
+	<location>release/2.3/miscapps-0.2.3.4.tgz</location>
+	<md5sum>fb70be71fd4c5a96e7206d929d46c3d0</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/miscapps/page.miscapps.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscapps/page.miscapps.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/miscapps/page.miscapps.php (original)
+++ freepbx-modules/trunk/modules/miscapps/page.miscapps.php Mon Apr  7 13:18:05 2008
@@ -1,5 +1,5 @@
 <?php 
-/** Misc Applications module for freePBX 2.2+
+/** Misc Applications module for FreePBX 2.2+
  * Copyright 2006 Greg MacLellan
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -22,7 +22,7 @@
 $dest = isset($_POST['dest']) ? $_POST['dest'] :  '';
 $enabled = isset($_POST['enabled']) ? (!empty($_POST['enabled'])) : true;
 
-if ($_POST['goto0']) {
+if (isset($_POST['goto0']) && $_POST['goto0']) {
 	$dest = $_POST[ $_POST['goto0'].'0' ];
 }
 
@@ -76,7 +76,7 @@
 
 }
 
-$helptext = _("Misc Applications are for adding feature codes that you can dial from internal phones that go to various destinations available in freePBX. This is in contrast to the <strong>Misc Destinations</strong> module, which is for creating destinations that can be used by other freePBX modules to dial internal numbers or feature codes.");
+$helptext = _("Misc Applications are for adding feature codes that you can dial from internal phones that go to various destinations available in FreePBX. This is in contrast to the <strong>Misc Destinations</strong> module, which is for creating destinations that can be used by other FreePBX modules to dial internal numbers or feature codes.");
 echo "<p>".$helptext."</p>\n";
 ?>
 

Added: freepbx-modules/trunk/modules/miscapps/uninstall.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscapps/uninstall.sql?rev=5512&op=file
==============================================================================
    (empty)

Added: freepbx-modules/trunk/modules/miscdests/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscdests/install.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/miscdests/install.php (added)
+++ freepbx-modules/trunk/modules/miscdests/install.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,19 @@
+<?php
+
+global $db;
+global $amp_conf;
+
+$autoincrement = (($amp_conf["AMPDBENGINE"] == "sqlite") || ($amp_conf["AMPDBENGINE"] == "sqlite3")) ? "AUTOINCREMENT":"AUTO_INCREMENT";
+
+$sql = "CREATE TABLE IF NOT EXISTS miscdests (
+	id INTEGER NOT NULL PRIMARY KEY $autoincrement,
+	description VARCHAR( 100 ) NOT NULL ,
+	destdial VARCHAR( 100 ) NOT NULL
+)";
+
+$check = $db->query($sql);
+if(DB::IsError($check)) {
+	die_freepbx("Can not create miscdests table\n");
+}
+
+?>

Modified: freepbx-modules/trunk/modules/miscdests/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscdests/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/miscdests/install.sql (original)
+++ freepbx-modules/trunk/modules/miscdests/install.sql Mon Apr  7 13:18:05 2008
@@ -1,1 +1,1 @@
-CREATE TABLE IF NOT EXISTS `miscdests` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `description` VARCHAR( 100 ) NOT NULL , `destdial` VARCHAR( 100 ) NOT NULL ) TYPE = MYISAM ;
+# empty file

Modified: freepbx-modules/trunk/modules/miscdests/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscdests/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/miscdests/module.xml (original)
+++ freepbx-modules/trunk/modules/miscdests/module.xml Mon Apr  7 13:18:05 2008
@@ -1,11 +1,14 @@
 <module>
 	<rawname>miscdests</rawname>
 	<name>Misc Destinations</name>
-	<version>1.3.4</version>
+	<version>1.3.4.3</version>
 	<type>setup</type>
-	<category>Inbound Call Control</category>
+	<category>Internal Options &amp; Configuration</category>
 	<description>Allows creating destinations that dial any local number (extensions, feature codes, outside phone numbers) that can be used by other modules (eg, IVR, time conditions) as a call destination.</description>
 	<changelog>
+		*1.3.4.3* changed categories
+		*1.3.4.2* bump for rc1
+		*1.3.4.1* changed freePBX to FreePBX
 		*1.3.4* destination changed from Dial(Local/nnn at from-internal) to Goto(from-internal,nnn,1), no reason a new channel should be created
 		*1.3.3* Minor formatting changes
 		*1.3.2* Add he_IL translation
@@ -15,7 +18,6 @@
 	<menuitems>
 		<miscdests>Misc Destinations</miscdests>
 	</menuitems>
-	<location>release/2.2/miscdests-1.3.4.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-MiscDests</info>
-	<md5sum>ada9ecba2c327cdf46ff3089c3af5549</md5sum>
+	<location>release/2.3/miscdests-1.3.4.2.tgz</location>
+	<md5sum>550b8a0080e533941eb2f0280cd2fbad</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/miscdests/page.miscdests.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscdests/page.miscdests.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/miscdests/page.miscdests.php (original)
+++ freepbx-modules/trunk/modules/miscdests/page.miscdests.php Mon Apr  7 13:18:05 2008
@@ -94,7 +94,9 @@
 	$delURL = $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'].'&action=delete';
 
 
-$helptext = _("Misc Destinations are for adding destinations that can be used by other freePBX modules, generally used to route incoming calls. If you want to create feature codes that can be dialed by internal users and go to various destinations, please see the <strong>Misc Applications</strong> module.");
+echo "<h2>"._("Misc Destinations")."</h2>";
+echo "<h3>"._("Instructions")."</h3>";
+$helptext = _("Misc Destinations are for adding destinations that can be used by other FreePBX modules, generally used to route incoming calls. If you want to create feature codes that can be dialed by internal users and go to various destinations, please see the <strong>Misc Applications</strong> module.");
 
 
 	

Modified: freepbx-modules/trunk/modules/miscdests/uninstall.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/miscdests/uninstall.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/miscdests/uninstall.sql (original)
+++ freepbx-modules/trunk/modules/miscdests/uninstall.sql Mon Apr  7 13:18:05 2008
@@ -1,1 +1,1 @@
-DROP TABLE IF NOT EXISTS `miscdests`;
+DROP TABLE IF EXISTS `miscdests`;

Modified: freepbx-modules/trunk/modules/music/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/music/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/music/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/music/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -1,6 +1,7 @@
 <?php
 
 function music_list($path) {
+	global $amp_conf;
 	$i = 1;
 	$arraycount = 0;
 	
@@ -19,6 +20,10 @@
 	}
 	if (isset($filearray)) {
 		sort($filearray);
+		// add a none categoy for no music
+		if (!in_array("none",$filearray)) {
+			$filearray[($i++)] = "none";
+		}
 		return ($filearray);
 	} else {
 		return null;

Modified: freepbx-modules/trunk/modules/music/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/music/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/music/install.php (original)
+++ freepbx-modules/trunk/modules/music/install.php Mon Apr  7 13:18:05 2008
@@ -1,4 +1,4 @@
-<? 
+<?php
 global $asterisk_conf;
 require_once("modules/music/functions.inc.php");
 

Modified: freepbx-modules/trunk/modules/music/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/music/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/music/module.xml (original)
+++ freepbx-modules/trunk/modules/music/module.xml Mon Apr  7 13:18:05 2008
@@ -1,24 +1,31 @@
 <module>
 	<rawname>music</rawname>
 	<name>Music on Hold</name>
-	<version>1.5</version>
+	<version>1.5.1.5</version>
+	<candisable>no</candisable>
+	<canuninstall>no</canuninstall>
 	<type>setup</type>
 	<category>Internal Options &amp; Configuration</category>
 	<description>Uploading and management of sound files (wav, mp3) to be used for on-hold music.</description>
 	<changelog>
-	*1.5* Fixed upload bug, #1646 could not upload files
-	*1.4.2* List wav files
-	*1.4.1* Add redirect_standard() call to avoid #1616
-	*1.4* Fix an issue of a new install not having a working MOH until they visit the page.
-	*1.3.2* Add he_IL translation
-	*1.3.1* Changed name to Music on Hold (from On Hold Music) 
-	*1.3* Bumped version to assist upgraders from the 2.1 tree. No other changes.
-	*1.2* First release for FreePBX 2.2 - Fixed compatibility issue with new UI
+		*1.5.1.5* #2193 moh path hardcoded
+		*1.5.1.4* bump for rc1
+		*1.5.1.3* #1969 fix javascript validation, add canunninstall:no
+		*1.5.1.2* #2070 fix proper use of script tags
+		*1.5.1.1* added candisable = no for module admin
+		*1.5.1* Added a 'none' category that results in silence played
+		*1.5* Fixed upload bug, #1646 could not upload files
+		*1.4.2* List wav files
+		*1.4.1* Add redirect_standard() call to avoid #1616
+		*1.4* Fix an issue of a new install not having a working MOH until they visit the page.
+		*1.3.2* Add he_IL translation
+		*1.3.1* Changed name to Music on Hold (from On Hold Music) 
+		*1.3* Bumped version to assist upgraders from the 2.1 tree. No other changes.
+		*1.2* First release for FreePBX 2.2 - Fixed compatibility issue with new UI
 	</changelog>
 	<menuitems>
 		<music>Music on Hold</music>
 	</menuitems>
-	<location>release/2.2/music-1.4.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-OHM</info>
-	<md5sum>262936ab17e92413fca52618425881b8</md5sum>
+	<location>release/2.3/music-1.5.1.4.tgz</location>
+	<md5sum>9e119508231e205de5d46719c900188e</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/music/page.music.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/music/page.music.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/music/page.music.php (original)
+++ freepbx-modules/trunk/modules/music/page.music.php Mon Apr  7 13:18:05 2008
@@ -1,4 +1,4 @@
-<?php /* $Id: page.music.php 3623 2007-01-23 21:54:27Z naftali5 $ */
+<?php /* $Id: page.music.php 4913 2007-08-21 04:49:30Z p_lindheimer $ */
 //Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
 //
 //This program is free software; you can redistribute it and/or
@@ -50,7 +50,7 @@
 	break;
 	case "delete":
 		music_rmdirr("$path_to_dir"); 
-		$path_to_dir = "/var/lib/asterisk/mohmp3"; //path to directory u want to read.
+		$path_to_dir = $asterisk_conf['astvarlibdir']."/mohmp3"; //path to directory u want to read.
 		$category='default';
 		createmusicconf();
 		needreload();
@@ -69,7 +69,9 @@
 $tresults = music_list($asterisk_conf['astvarlibdir']."/mohmp3");
 if (isset($tresults)) {
 	foreach ($tresults as $tresult) {
-		echo "<li><a id=\"".($category==$tresult ? 'current':'')."\" href=\"config.php?display=".urlencode($display)."&category=".urlencode($tresult)."&action=edit\">{$tresult}</a></li>";
+		if ($tresult != "none") {
+			echo "<li><a id=\"".($category==$tresult ? 'current':'')."\" href=\"config.php?display=".urlencode($display)."&category=".urlencode($tresult)."&action=edit\">{$tresult}</a></li>";
+		}
 	}
 }
 ?>
@@ -85,6 +87,14 @@
 	$tresults = music_list($asterisk_conf['astvarlibdir']."/mohmp3");
 	if (isset($tresults)) {
 		foreach ($tresults as $tresult)  {
+			// hack - but his is all a hack until redone, in functions, etc.
+			// this puts a none category to allow no music to be chosen
+			//
+			if ($tresult == "none") {
+				$dir = "/dev/null";
+				$File_Write.="[{$tresult}]\nmode=files\ndirectory={$dir}\n";
+				continue;
+			}
 			if ($tresult != "default" ) {
 				$dir = $asterisk_conf['astvarlibdir']."/mohmp3/{$tresult}/";
 			} else {
@@ -97,6 +107,7 @@
 			}
 		}
 	}
+
 
 	$handle = fopen("/etc/asterisk/musiconhold_additional.conf", "w");
 
@@ -216,10 +227,13 @@
 
 function addcategory_onsubmit() {
 	var msgInvalidCategoryName = "<?php echo _('Please enter a valid Category Name'); ?>";
+	var msgReservedCategoryName = "<?php echo _('Categories: \"none\" and \"default\" are reserved names. Please enter a different name'); ?>";
 
 	defaultEmptyOK = false;
 	if (!isAlphanumeric(theForm.category.value))
 		return warnInvalid(theForm.category, msgInvalidCategoryName);
+	if (theForm.category.value == "default" || theForm.category.value == "none")
+		return warnInvalid(theForm.category, msgReservedCategoryName);
 	
 	return true;
 }

Modified: freepbx-modules/trunk/modules/paging/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/paging/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/paging/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/paging/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -7,51 +7,6 @@
    check for version upgrades, etc, of the paging database, to
    allow for easy upgrades. */
 
-function paging_init() {
-	global $db;
-	
-	// Check to make sure that install.sql has been run
-	$sql = "SELECT * from paging_overview";
-	$results = $db->getAssoc($sql);
-	
-	if (DB::IsError($results)) {
-		// It couldn't locate the table. This is bad. Lets try to re-create it, just
-		// in case the user has had the brilliant idea to delete it. 
-		// in 2.2, replace this with just runModuleSQL which is in admin/functions.inc.php
-		pagingrunModuleSQL('paging', 'uninstall');
-		if (pagingrunModuleSQL('paging', 'install')==false) {
-			echo _("There is a problem with install.sql, cannot re-create databases. Contact support\n");
-			die;
-		} else {
-			echo _("Database was deleted! Recreated successfully.<br>\n");
-			$results = $db->getAll($sql);
-		}
-	}
-	if (!isset($results['version'])) {
-		print "First-time use. Propogating databases.<br>\n";
-		// Here, you load up a current database schema. Below, if the version is 
-		// different, you'd write some upgrade code. This is better than doing it
-		// in install.sql, becuase you don't know what's in there already. 
-		$sql = "INSERT INTO paging_overview VALUES ('version', 1)";
-		$db->query($sql);
-		/* Load up the phone definitions */
-		$fd = fopen("modules/paging/phones.sql","r");
-		while (!feof($fd)) {
-			$data = fgets($fd, 1024);
-			if ($data{0}!=';' && $data{0}!='#' && strlen($data) > 3) {
-				// It's not a comment or a blank(ish) line. Add it.
-				$phoneresult = $db->query($data);
-				if(DB::IsError($phoneresult)) 
-					die($phoneresult->getMessage()."<br><br>error adding to phones table");
-			}
-		}
-		fclose($fd);
-		print "Init complete. Please click on this page again to start using this module<br>\n";
-		exit;
-	} /* else ... check the version and upgrade if needed. */
-}
-
-
 //	Generates dialplan for paging  - is called from retrieve_conf
 
 function paging_get_config($engine) {
@@ -59,6 +14,67 @@
 	global $ext; 
 	switch($engine) {
 		case "asterisk":
+			// setup for intercom
+			$fcc = new featurecode('paging', 'intercom-prefix');
+			$code = $fcc->getCodeActive();
+			unset($fcc);
+
+			// Since these are going down channel local, set ALERT_INFO and SIPADDHEADER which will be set in dialparties.agi
+			// no point in even setting the headers here they will get lost in channel local
+			//
+			if (!empty($code)) {
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_setvar('dialnumber', '${EXTEN:'.strlen($code).'}'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_dbget('user-intercom','AMPUSER/${dialnumber}/intercom'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_gotoif('$["${user-intercom}" = "disabled" ]', 'nointercom'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_setvar('__SIPADDHEADER', 'Call-Info: \;answer-after=0'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_setvar('__ALERT_INFO', 'Ring Answer'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_setvar('__SIP_URI_OPTIONS', 'intercom=true'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_macro('user-callerid'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_dial('Local/${dialnumber}@from-internal/n','',''));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_busy());
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_macro('hangupcall'));
+				$ext->add('ext-intercom', '_'.$code.'.', 'nointercom', new ext_noop('Intercom disallowed by ${dialnumber}'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_playback('intercom&for&extension'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_saydigits('${dialnumber}'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_playback('is&disabled'));
+				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_congestion());
+
+				$userlist = core_users_list();
+				if (is_array($userlist)) {
+					foreach($userlist as $item) {
+						$intercom_code = $code.$item[0];
+						$ext->add('ext-intercom-users', '_'.$intercom_code, '', new ext_goto('ext-intercom,${EXTEN},1'));
+					}
+				}
+				$ext->addInclude('from-internal-additional', 'ext-intercom-users');
+			
+				$fcc = new featurecode('paging', 'intercom-on');
+				$oncode = $fcc->getCodeActive();
+				unset($fcc);
+
+				if ($oncode) {
+					$ext->add('ext-intercom-users', $oncode, '', new ext_answer(''));
+					$ext->add('ext-intercom-users', $oncode, '', new ext_wait('1'));
+					$ext->add('ext-intercom-users', $oncode, '', new ext_macro('user-callerid'));
+					$ext->add('ext-intercom-users', $oncode, '', new ext_setvar('DB(AMPUSER/${AMPUSER}/intercom)', 'enabled'));
+					$ext->add('ext-intercom-users', $oncode, '', new ext_playback('intercom&enabled'));
+					$ext->add('ext-intercom-users', $oncode, '', new ext_macro('hangupcall'));
+				}
+			
+				$fcc = new featurecode('paging', 'intercom-off');
+				$offcode = $fcc->getCodeActive();
+				unset($fcc);
+	
+				if ($offcode) {
+					$ext->add('ext-intercom-users', $offcode, '', new ext_answer(''));
+					$ext->add('ext-intercom-users', $offcode, '', new ext_wait('1'));
+					$ext->add('ext-intercom-users', $offcode, '', new ext_macro('user-callerid'));
+					$ext->add('ext-intercom-users', $offcode, '', new ext_setvar('DB(AMPUSER/${AMPUSER}/intercom)', 'disabled'));
+					$ext->add('ext-intercom-users', $offcode, '', new ext_playback('intercom&disabled'));
+					$ext->add('ext-intercom-users', $offcode, '', new ext_macro('hangupcall'));
+				}
+			}
+
 			// Get a list of all the phones used for paging
 			$sql = "SELECT DISTINCT ext FROM paging_groups";
 			$results = $db->getAll($sql);
@@ -80,7 +96,7 @@
 					$skipheaders = true;
 				}
 				
-				$ext->add('ext-paging', "PAGE${xtn}", '', new ext_gotoif('$[ ${CALLERID(number)} = '.$xtn.' ]','skipself'));
+				$ext->add('ext-paging', "PAGE${xtn}", '', new ext_gotoif('$[ ${AMPUSER} = '.$xtn.' ]','skipself'));
 				$ext->add('ext-paging', "PAGE${xtn}", '', new ext_gotoif('$[ ${FORCE_PAGE} != 1 ]','AVAIL'));
 				$ext->add('ext-paging', "PAGE${xtn}", '', new ext_setvar('AVAILSTATUS', 'not checked'));
 				$ext->add('ext-paging', "PAGE${xtn}", '', new ext_goto('SKIPCHECK'));
@@ -88,8 +104,8 @@
 				$ext->add('ext-paging', "PAGE${xtn}", 'SKIPCHECK', new ext_noop('Seems to be available (state = ${AVAILSTATUS}'));
 				
 				if (!$skipheaders) {
-					$ext->add('ext-paging', "PAGE${xtn}", '', new ext_setvar('__SIPADDHEADER', 'Call-Info: \;answer-after=0'));
-					$ext->add('ext-paging', "PAGE${xtn}", '', new ext_setvar('__ALERT_INFO', 'Ring Answer'));
+					$ext->add('ext-paging', "PAGE${xtn}", '', new ext_sipaddheader('Call-Info','\;answer-after=0'));
+					$ext->add('ext-paging', "PAGE${xtn}", '', new ext_alertinfo('Ring Answer'));
 					$ext->add('ext-paging', "PAGE${xtn}", '', new ext_setvar('__SIP_URI_OPTIONS', 'intercom=true'));
 				}
 				
@@ -117,68 +133,14 @@
 				// It will always end with an &, so lets take that off.
 				$dialstr = rtrim($dialstr, "&");
 				$ext->add('ext-paging', "Debug", '', new ext_noop("dialstr is $dialstr"));
+				$ext->add('ext-paging', $grp, '', new ext_answer(''));
 				$ext->add('ext-paging', $grp, '', new ext_setvar("_FORCE_PAGE", ($thisgroup['force_page']?1:0)));
 				$ext->add('ext-paging', $grp, '', new ext_macro('user-callerid'));
+				// make AMPUSER inherited here, so we can skip the proper 'self' if using cidnum masquerading
+				$ext->add('ext-paging', $grp, '', new ext_setvar('_AMPUSER', '${AMPUSER}'));
 				$ext->add('ext-paging', $grp, '', new ext_page($dialstr));
 			}
 			
-
-			
-			// setup for intercom
-			$fcc = new featurecode('paging', 'intercom-prefix');
-			$code = $fcc->getCodeActive();
-			unset($fcc);
-
-			if (!empty($code)) {
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_setvar('dialnumber', '${EXTEN:'.strlen($code).'}'));
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_dbget('user-intercom','AMPUSER/${dialnumber}/intercom'));
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_gotoif('$["${user-intercom}" = "disabled" ]', 'nointercom'));
-				
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_setvar('__SIPADDHEADER', 'Call-Info: \;answer-after=0'));
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_setvar('__ALERT_INFO', 'Ring Answer'));
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_setvar('__SIP_URI_OPTIONS', 'intercom=true'));
-
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_dial('Local/${dialnumber}@from-internal/n','',''));
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_busy());
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_macro('hangupcall'));
-				$ext->add('ext-intercom', '_'.$code.'.', 'nointercom', new ext_noop('Intercom disallowed by ${dialnumber}'));
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_playback('intercom&for&extension'));
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_saydigits('${dialnumber}'));
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_playback('is&disabled'));
-				$ext->add('ext-intercom', '_'.$code.'.', '', new ext_congestion());
-			
-			
-
-				$ext->addInclude('from-internal-additional', 'ext-intercom');
-			
-			
-				$fcc = new featurecode('paging', 'intercom-on');
-				$oncode = $fcc->getCodeActive();
-				unset($fcc);
-
-				if ($oncode) {
-					$ext->add('ext-intercom', $oncode, '', new ext_answer('')); // $cmd,1,Answer
-					$ext->add('ext-intercom', $oncode, '', new ext_wait('1')); // $cmd,n,Wait(1)
-					$ext->add('ext-intercom', $oncode, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-					$ext->add('ext-intercom', $oncode, '', new ext_setvar('DB(AMPUSER/${CALLERID(number)}/intercom)', 'enabled')); // $cmd,n,Set(...=enabled)
-					$ext->add('ext-intercom', $oncode, '', new ext_playback('intercom&enabled')); // $cmd,n,Playback(...)
-					$ext->add('ext-intercom', $oncode, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
-				}			
-			
-				$fcc = new featurecode('paging', 'intercom-off');
-				$offcode = $fcc->getCodeActive();
-				unset($fcc);
-	
-				if ($offcode) {
-					$ext->add('ext-intercom', $offcode, '', new ext_answer('')); // $cmd,1,Answer
-					$ext->add('ext-intercom', $offcode, '', new ext_wait('1')); // $cmd,n,Wait(1)
-					$ext->add('ext-intercom', $offcode, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-					$ext->add('ext-intercom', $offcode, '', new ext_setvar('DB(AMPUSER/${CALLERID(number)}/intercom)', 'disabled')); // $cmd,n,Set(...=disabled)
-					$ext->add('ext-intercom', $offcode, '', new ext_playback('intercom&disabled')); // $cmd,n,Playback(...)
-					$ext->add('ext-intercom', $offcode, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
-				}
-			}
-
 		break;
 	}
 }
@@ -247,14 +209,14 @@
 	$res = $db->query($sql);
 	if (DB::isError($res)) {
 		var_dump($res);
-		die("Error in paging_del(): ");
+		die_freepbx("Error in paging_del(): ");
 	}
 	
 	$sql = "DELETE FROM paging_config WHERE page_group='$xtn'";
 	$res = $db->query($sql);
 	if (DB::isError($res)) {
 		var_dump($res);
-		die("Error in paging_del(): ");
+		die_freepbx("Error in paging_del(): ");
 	}
 	
 	needreload();

Modified: freepbx-modules/trunk/modules/paging/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/paging/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/paging/install.php (original)
+++ freepbx-modules/trunk/modules/paging/install.php Mon Apr  7 13:18:05 2008
@@ -21,31 +21,87 @@
 $fcc->update();
 unset($fcc);	
 
+$sql = "CREATE TABLE IF NOT EXISTS paging_overview 
+	( config VARCHAR(50), 
+	  detail VARCHAR(25)
+	)";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	die_freepbx($result->getDebugInfo());
+}
+
+$sql = "CREATE TABLE IF NOT EXISTS paging_groups 
+	( page_number VARCHAR(50), 
+	  ext VARCHAR(25)
+	)";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	die_freepbx($result->getDebugInfo());
+}
+
+$sql = "CREATE TABLE IF NOT EXISTS paging_phones 
+	( phone_name VARCHAR(50), 
+	  priority INT, 
+		command VARCHAR(50)
+	)";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	die_freepbx($result->getDebugInfo());
+}
 
 // version 1.6 upgrade
 $sql = "SELECT page_group FROM paging_config";
 $check = $db->getRow($sql, DB_FETCHMODE_ASSOC);
 if(DB::IsError($check)) {
 	// this table wasn't used up to this point, replace it with the new one
-	$sql = "DROP TABLE paging_config;";
+	$sql = "DROP TABLE IF EXISTS paging_config;";
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getDebugInfo());
+		die_freepbx($result->getDebugInfo());
 	}
 	
-	$sql = "CREATE TABLE IF NOT EXISTS paging_config ( page_group VARCHAR(50), force_page INTEGER(1) NOT NULL);";
+	$sql = "CREATE TABLE IF NOT EXISTS paging_config 
+		( page_group VARCHAR(255), 
+	  	force_page INTEGER(1) NOT NULL
+		)";
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getDebugInfo());
+		die_freepbx($result->getDebugInfo());
 	}
 
 	// insert default values
 	$sql = "INSERT INTO paging_config  SELECT DISTINCT page_number, 0 FROM paging_groups;";
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getDebugInfo());
+		die_freepbx($result->getDebugInfo());
 	}
 }
-				    
+// These are the three most common ways of auto answering.
+// Set them up for now - this will all change when paging gets modified
+// (I don't think this is even being used)
+//
+$sql = "INSERT INTO paging_phones VALUES ('GXP-2000', 1, 'Set(SIPADDHEADER=\"Call-Info: answer-after=0\")')";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	die_freepbx($result->getDebugInfo());
+}
+$sql = "INSERT INTO paging_phones VALUES ('Polycom', 1, 'Set(ALERT_INFO=\"Ring Answer\")')";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	die_freepbx($result->getDebugInfo());
+}
+$sql = "INSERT INTO paging_phones VALUES ('Snom', 1, 'Set(SIP_URI_OPTIONS=\"intercom=true\")')";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	die_freepbx($result->getDebugInfo());
+}
+
+// Now mark the version - again, not even sure if this is in use anymore
+//
+$sql = "INSERT INTO paging_overview VALUES ('version', 1)";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	die_freepbx($result->getDebugInfo());
+}
 
 ?>

Modified: freepbx-modules/trunk/modules/paging/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/paging/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/paging/install.sql (original)
+++ freepbx-modules/trunk/modules/paging/install.sql Mon Apr  7 13:18:05 2008
@@ -1,4 +1,0 @@
-CREATE TABLE IF NOT EXISTS paging_overview ( config VARCHAR(50) , detail VARCHAR(25)); 
-CREATE TABLE IF NOT EXISTS paging_groups ( page_number VARCHAR(50) , ext VARCHAR(25)); 
-CREATE TABLE IF NOT EXISTS paging_config ( page_group VARCHAR(50), force_page INTEGER(1) NOT NULL);
-CREATE TABLE IF NOT EXISTS paging_phones ( phone_name VARCHAR(50), priority INT, command VARCHAR(50));

Modified: freepbx-modules/trunk/modules/paging/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/paging/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/paging/module.xml (original)
+++ freepbx-modules/trunk/modules/paging/module.xml Mon Apr  7 13:18:05 2008
@@ -1,11 +1,18 @@
 <module>
 	<rawname>paging</rawname>
 	<name>Paging and Intercom</name>
-	<version>1.6.3</version>
+	<version>1.6.6.2</version>
 	<type>setup</type>
 	<category>Internal Options &amp; Configuration</category>
 	<changelog>
-		*1.6.3* Add he_IL translation
+		*1.6.6.2* #2437 answer channle, page doesn't - and fix js validation allowing blank page groups
+		*1.6.6.1* #2376 enable/disable code broke in 1.6.6 and add user-callerid to get proper cid on intercom
+		*1.6.6* #2376 only interecept *80nnn for local extensions so branch offices can be intercomed
+		*1.6.5.2* bump for rc1
+		*1.6.5.1* #1861 create intercom dialplan always when enabled
+		*1.6.5* #2168 fix intercom, #2165 change module to get rid of first time propagation
+		*1.6.4* fixed deprecated use of ALERT_INFO and SIPHEADER
+		*1.6.3* changed ${CALLERID(number)} to ${AMPUSER} to accomodate CID number masquerading
 		*1.6.2* Fix callerid bug
 		*1.6.1* Fix install bug
 		*1.6* Busy devices are no longer paged, flag added to allow overriding this behaviour.
@@ -13,13 +20,15 @@
 		*1.5.1* Fixed bug with saving paging group
 		*1.5* First release for FreePBX 2.2 - Fixed compatibility issue with new UI
 	</changelog>
+	<requirements>
+		<version>2.3.0beta2</version>
+	</requirements>
 	<description>Allows creation of paging groups to make announcements using the speaker built into most SIP phones. 
 	
 	Also creates an Intercom feature code that can be used as a prefix to talk directly to one person, as well as optional feature codes to block/allow intercom calls.</description>
 	<menuitems>
 		<paging>Paging and Intercom</paging>
 	</menuitems>
-	<location>release/2.2/paging-1.6.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Paging</info>
-	<md5sum>50514bdaa419836f01962ca501c00f22</md5sum>
+	<location>release/2.3/paging-1.6.6.1.tgz</location>
+	<md5sum>608f60ae27fe977ed4d0043ecec1a79d</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/paging/page.paging.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/paging/page.paging.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/paging/page.paging.php (original)
+++ freepbx-modules/trunk/modules/paging/page.paging.php Mon Apr  7 13:18:05 2008
@@ -1,5 +1,5 @@
 <?php 
-/* $Id: page.paging.php 3217 2006-11-28 01:40:23Z gregmac $ */
+/* $Id: page.paging.php 5384 2007-12-10 18:39:19Z p_lindheimer $ */
 //Copyright (C) 2006 Rob Thomas (xrobau at gmail.com)
 //
 //This program is free software; you can redistribute it and/or
@@ -28,7 +28,6 @@
 <?php
 // Check to make sure that the paging database is propogated and
 // up to date.
-paging_init();
 
 switch ($action) {
 	case "add":
@@ -65,8 +64,8 @@
 			$rows = 5;
 		if ($rows > 20)
 			$rows = 20;
-		echo "<p><a href='".$_SERVER['PHP_SELF']."?type=${type}&amp;display=${display}&amp;action=delete";
-		echo "&amp;selection=${xtn}'>"._("Delete Group")." $xtn</a></p>";
+		echo "<a href='".$_SERVER['PHP_SELF']."?type=${type}&amp;display=${display}&amp;action=delete";
+		echo "&amp;selection=${xtn}'>"._("Delete Group")." $xtn</a>";
 	} else {
 		$rows = 5;
 	}
@@ -128,10 +127,12 @@
 	
 	var selected = 0;
 	for (var i=0; i < theForm.xtnlist.options.length; i++) {
-		if (theForm.xtnlist.options[i].checked) selected += 1;
+		if (theForm.xtnlist.options[i].selected) selected += 1;
 	}
 	if (selected < 1) {
-		return warnInvalid(theForm.xtnlist, msgInvalidExtList);
+		theForm.xtnlist.focus();
+		alert(msgInvalidExtList);
+		return false;
 	}
 		
 	return true;

Added: freepbx-modules/trunk/modules/paging/uninstall.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/paging/uninstall.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/paging/uninstall.php (added)
+++ freepbx-modules/trunk/modules/paging/uninstall.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,56 @@
+<?php
+
+// Enable intercom as a feature code
+echo "removing featurecode intercom-prefix..";
+$fcc = new featurecode('paging', 'intercom-prefix');
+$fcc->delete();
+unset($fcc);
+echo "done<br>\n";
+
+// User intercom enable code
+echo "removing featurecode intercom-on..";
+$fcc = new featurecode('paging', 'intercom-on');
+$fcc->delete();
+unset($fcc);
+echo "done<br>\n";
+
+// User intercom disable 
+echo "removing featurecode intercom-off..";
+$fcc = new featurecode('paging', 'intercom-off');
+$fcc->delete();
+unset($fcc);	
+echo "done<br>\n";
+
+echo "dropping table paging_overview..";
+$sql = "DROP TABLE IF EXISTS paging_overview";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	echo "ERROR DELETING TABLE: ".$result->getDebugInfo();
+}
+echo "done<br>\n";
+
+echo "dropping table paging_groups..";
+$sql = "DROP TABLE IF EXISTS paging_groups";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	echo "ERROR DELETING TABLE: ".$result->getDebugInfo();
+}
+echo "done<br>\n";
+
+echo "dropping table paging_phones..";
+$sql = "DROP TABLE IF EXISTS paging_phones";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	echo "ERROR DELETING TABLE: ".$result->getDebugInfo();
+}
+echo "done<br>\n";
+
+echo "dropping table paging_config..";
+$sql = "DROP TABLE IF EXISTS paging_config";
+$result = $db->query($sql);
+if(DB::IsError($result)) {
+	echo "ERROR DELETING TABLE: ".$result->getDebugInfo();
+}
+echo "done<br>\n";
+
+?>

Modified: freepbx-modules/trunk/modules/paging/uninstall.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/paging/uninstall.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/paging/uninstall.sql (original)
+++ freepbx-modules/trunk/modules/paging/uninstall.sql Mon Apr  7 13:18:05 2008
@@ -1,3 +1,0 @@
-DROP TABLE IF EXISTS paging_overview;
-DROP TABLE IF EXISTS paging_groups;
-DROP TABLE IF EXISTS paging_phones;

Modified: freepbx-modules/trunk/modules/parking/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/parking/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/parking/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/parking/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -85,7 +85,7 @@
 	$sql = "DELETE FROM parkinglot WHERE id = '$parkinglot_id'";
 	$result = $db->query($sql);
 	if(DB::IsError($result)) {
-		die($result->getMessage().$sql);
+		die_freepbx($result->getMessage().$sql);
 	}
 
 	// Check for interger only inputs and set to default if not
@@ -110,7 +110,7 @@
 
 	$result = $db->executeMultiple($compiled,$parkfields);
 	if(DB::IsError($result)) {
-		die($result->getDebugInfo()."<br><br>".'error adding to PARKING table');
+		die_freepbx($result->getDebugInfo()."<br><br>".'error adding to PARKING table');
 	}
 }
 

Added: freepbx-modules/trunk/modules/parking/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/parking/install.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/parking/install.php (added)
+++ freepbx-modules/trunk/modules/parking/install.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,26 @@
+<?php
+
+global $db;
+global $amp_conf;
+
+$results = array();
+$sql = "SELECT id, keyword, data FROM parkinglot WHERE keyword = 'goto'";
+$results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
+if (!DB::IsError($results)) { // error - table must not be there
+	foreach ($results as $result) {
+		$old_dest  = $result['data'];
+		$id        = $result['id'];
+		$keyword   = $result['keyword'];
+
+		$new_dest = merge_ext_followme(trim($old_dest));
+		if ($new_dest != $old_dest) {
+			$sql = "UPDATE parkinglot SET data = '$new_dest' WHERE id = '$id'  AND keyword = '$keyword' AND data = '$old_dest'";
+			$results = $db->query($sql);
+			if(DB::IsError($results)) {
+				die_freepbx($results->getMessage());
+			}
+		}
+	}
+}
+
+?>

Modified: freepbx-modules/trunk/modules/parking/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/parking/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/parking/module.xml (original)
+++ freepbx-modules/trunk/modules/parking/module.xml Mon Apr  7 13:18:05 2008
@@ -1,7 +1,7 @@
 <module>
 	<rawname>parking</rawname>
 	<name>Parking Lot</name>
-	<version>2.1.1</version>
+	<version>2.1.2.1</version>
 	<type>setup</type>
 	<category>Internal Options &amp; Configuration</category>
 	<description>Manages parking lot extensions and other options.
@@ -11,11 +11,12 @@
 		<parking>Parking Lot</parking>
 	</menuitems>
 	<changelog>
+		*2.1.2.1* bump for rc1
+		*2.1.2* merge findmefollow/core extension destinations if any
 		*2.1.1* fix pseudo hardcoded path issue (hardcoded form missing global)
 		*2.1* Remove settings on uninstall bug #1597
 		*2.0.2* Add he_IL translation
 	</changelog>
-	<location>release/2.2/parking-2.1.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-ParkingLot</info>
-	<md5sum>1c2ca325423c117580381a5ec4773d19</md5sum>
+	<location>release/2.3/parking-2.1.2.tgz</location>
+	<md5sum>693687106df687dccd1fd8bc140eba21</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/pbdirectory/agi-bin/pbdirectory
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/pbdirectory/agi-bin/pbdirectory?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/pbdirectory/agi-bin/pbdirectory (original)
+++ freepbx-modules/trunk/modules/pbdirectory/agi-bin/pbdirectory Mon Apr  7 13:18:05 2008
@@ -17,8 +17,12 @@
 
 */
 
-//define("AGIBIN_DIR", dirname(__FILE__));
-define("AGIBIN_DIR", '/var/lib/asterisk/agi-bin/');
+/* --------WARNING---------
+ * 
+ * This script is auto-copied from an included module and will get overwritten.
+ * If you modify it, you must change it to read only, in the agi-bin directory,
+ * to keep it from getting changed.
+ */
 
 // set to 1 to say "zed" instead of "zee"
 define("SAY_ZED",0);
@@ -48,7 +52,20 @@
 define("D_POUND",35);
 define("D_STAR",42);
 
-include(AGIBIN_DIR."/phpagi.php");
+include("phpagi.php");
+
+function get_var( $agi, $value)
+{
+	$r = $agi->get_variable( $value );
+	
+	if ($r['result'] == 1)
+	{
+		$result = $r['data'];
+		return $result;
+	}
+	else
+		return '';
+}
 
 function output(&$var) {
 	if (DEBUG) {
@@ -64,40 +81,17 @@
 	}
 }
 
-function parse_amportal_conf($filename) {
-	$file = file($filename);
-	if (is_array($file)) {
-		foreach ($file as $line) {
-			if (preg_match("/^\s*([a-zA-Z0-9]+)=([a-zA-Z0-9 .&-@=_<>\"\']+)\s*$/",$line,$matches)) {
-				$conf[ $matches[1] ] = $matches[2];
-			}
-		}
-	} else {
-		die("<h1>Missing or unreadable config file ($filename)...cannot continue</h1>");
-	}
-	
-	if ( !isset($conf["AMPDBENGINE"]) || ($conf["AMPDBENGINE"] == ""))
-	{
-		$conf["AMPDBENGINE"] = "mysql";
-	}
-
-/*			
-	if (($amp_conf["AMPDBENGINE"] == "sqlite") && (!isset($amp_conf["AMPDBENGINE"])))
-		$amp_conf["AMPDBFILE"] = "/var/lib/freepbx/freepbx.sqlite";
-*/
-	
-	return $conf;
-}
-
 function phonebook_list() {
-	global $amp_conf;
-
+
+	global $ampmgruser, $ampmgrpass;
+
+	$numbers = array();
 	$astman = new AGI_AsteriskManager();
-	if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {
+	if ($res = $astman->connect("127.0.0.1", $ampmgruser , $ampmgrpass)) {
 		$list = $astman->database_show();
 		foreach ($list as $k => $v)	{
 			if (substr($k, 1, 7) == 'cidname')
-			$numbers[substr($k, 9)] = $v ;
+				$numbers[substr($k, 9)] = $v ;
 		}
 
 		if (is_array($numbers))
@@ -105,7 +99,7 @@
 
 		return $numbers;
 	} else {
-		fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
+		fatal("Cannot connect to Asterisk Manager with ".$ampmgruser."/".$ampmgrpass);
 	}
 
 }
@@ -249,7 +243,7 @@
 	return stream_multiple($files,$escape_digits);
 }
 
-function do_directory($type, &$directory, $dial_context, $say_exten, $operator) {
+function do_directory($type, &$directory, $say_exten, $operator) {
 	global $agi;
 
 	$agi->conlog('starting directory');
@@ -364,8 +358,10 @@
 /******************************************************************************/
 $agi = new AGI;
 
+$ampmgruser  = get_var( $agi, "AMPMGRUSER" );
+$ampmgrpass  = get_var( $agi, "AMPMGRPASS" );
+
 if (DEBUG) $logfile = fopen("/tmp/pbdirectory.log","w");
-$amp_conf = parse_amportal_conf('/etc/amportal.conf');
 
 $phonebook = phonebook_list();
 
@@ -417,6 +413,6 @@
 }
 
 $agi->verbose('test');
-do_directory($dir_type, $directory, $dial_context, $say_exten, $operator);
+do_directory($dir_type, $directory, $say_exten, $operator);
 	
 ?>

Modified: freepbx-modules/trunk/modules/pbdirectory/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/pbdirectory/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/pbdirectory/module.xml (original)
+++ freepbx-modules/trunk/modules/pbdirectory/module.xml Mon Apr  7 13:18:05 2008
@@ -1,18 +1,26 @@
 <module>
 	<rawname>pbdirectory</rawname>
 	<name>Phonebook Directory</name>
-	<version>0.3</version>
+	<version>0.3.1.3</version>
 	<type>tool</type>
 	<category>CID &amp; Number Management</category>
-	<location>release/2.2/pbdirectory-2.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Features</info>
+	<location>release/2.3/pbdirectory-0.3.1.2.tgz</location>
 	<description>Provides a dial-by-name directory for phonebook entries</description>
+	<changelog>
+		*0.3.1.3* changed requirements 2.2 to depends
+		*0.3.1.2* #2343 pbdirectory script errors
+		*0.3.1.1* bump for rc1
+		*0.3.1* fixed some hard coded paths, requires core modules:  2.3.0beta1.6 or above
+		*0.3* First changelog entry
+	</changelog>
+	<depends>
+		<version>2.2</version>
+	</depends>
 	<requirements>
-		<version>2.2</version>
 		<module>phonebook</module>
 		<module>speeddial</module>
 	</requirements>
-	<md5sum>bc2a70884c09377ef212dd6e02c32cb7</md5sum>
+	<md5sum>c40f7a1208403bac111fa17ccc0f20a5</md5sum>
 	<changelog>
 	</changelog>
 </module>

Modified: freepbx-modules/trunk/modules/phonebook/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/phonebook/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/phonebook/module.xml (original)
+++ freepbx-modules/trunk/modules/phonebook/module.xml Mon Apr  7 13:18:05 2008
@@ -1,24 +1,30 @@
 <module>
 	<rawname>phonebook</rawname>
 	<name>Phonebook</name>
-	<version>1.1.5</version>
-	<description>Provides a phonebook for freePBX, it can be used as base for Caller ID Lookup and Speed Dial</description>
+	<version>1.1.5.7</version>
+	<description>Provides a phonebook for FreePBX, it can be used as base for Caller ID Lookup and Speed Dial</description>
 	<type>tool</type>
-	<category>CID &amp; Number Management</category>
+	<category>System Administration</category>
 	<menuitems>
-		<phonebook>Asterisk Phonebook</phonebook>
+		<phonebook needsenginedb="yes">Asterisk Phonebook</phonebook>
 	</menuitems>
-	<location>release/2.2/phonebook-1.1.4.tgz</location>
-	<md5sum>6326ee297c853f3c9b4cec8655d17eaf</md5sum>
-	<info>http://freepbx.org/wiki/AsteriskPhonebook</info>
+	<location>release/2.3/phonebook-1.1.5.6.tgz</location>
+	<md5sum>ddd2f3eedff4d6a60b12abeedfcc5fd8</md5sum>
 	<changelog>
+		*1.1.5.7* changed categories
+		*1.1.5.6* bump for rc1
+		*1.1.5.5* added xml attribute needsenginedb
+		*1.1.5.4* #2163 fix syntax error
+		*1.1.5.3* #2070 fix proper use of script tags
+		*1.1.5.2* bumping to remove checksum error
+		*1.1.5.1* changed freePBX to FreePBX
 		*1.1.5* Fixed a Warning when phonebook was empty
 		*1.1.4* Automatically generate Speed Dial Code if not supplied by user
 			Sort Phonebook alphabetically
 			Reuse Asterisk Manager connection
 		*1.1.3* Fixed copyright information for fgetcsvfromline()
 			Updated module.xml format
-		*1.1.2* freePBX 2.1.2 Released
+		*1.1.2* FreePBX 2.1.2 Released
 		*1.1.1* Apply #1105 - Fix up module naming conventions
 		*1.1.0* Added Speed dial field for phonebook entries (used by speeddial module)
 			Changed phonebook_list() return value

Modified: freepbx-modules/trunk/modules/phonebook/page.phonebook.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/phonebook/page.phonebook.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/phonebook/page.phonebook.php (original)
+++ freepbx-modules/trunk/modules/phonebook/page.phonebook.php Mon Apr  7 13:18:05 2008
@@ -26,15 +26,19 @@
 	switch ($action) {
 		case "add":
 			phonebook_add($number, $name, $speeddial);
+			redirect_standard();
+		exit;
 		break;
 		case "delete":
 			$numbers = phonebook_list();
 			phonebook_del($number, $numbers[$number]['speeddial']);
+			redirect_standard();
 		break;
 		case "edit":
 			$numbers = phonebook_list();
 			phonebook_del($editnumber, $numbers[$editnumber]['speeddial']);
 			phonebook_add($number, $name, $speeddial);
+			redirect_standard();
 		break;
 		case "empty":
 			phonebook_empty();
@@ -54,6 +58,7 @@
 							$i++;
 						}
 					}
+					redirect_standard();
 				}
 			} else
 				$n = 0; // total lines if no file
@@ -64,7 +69,7 @@
 			$numbers = phonebook_list();
 			foreach ($numbers as $number => $values)
 				printf("\"%s\";%s;%s\n", $values['name'], $number, $values['speeddial']);
-			die();
+			die_freepbx();
 		break;
 	}
 }
@@ -93,8 +98,8 @@
 
 <table cellpadding="5" width="100%">
 
-<form autocomplete="off" name="delete" action="<?php $_SERVER['PHP_SELF'] ?>" method="post" onsubmit="return confirm('<? echo _("Are you sure you want to empty your phonebook ?")?>');">
-<?#onsubmit="return edit_onsubmit();"?>
+<form autocomplete="off" name="delete" action="<?php $_SERVER['PHP_SELF'] ?>" method="post" onsubmit="return confirm('<?php echo _("Are you sure you want to empty your phonebook ?")?>');">
+<?php#onsubmit="return edit_onsubmit();"?>
 	<input type="hidden" name="action" value="empty">
 
 	<tr>
@@ -102,9 +107,9 @@
 	</tr>
 
 	<tr>
-		<td><b><?=_("Number")?></b></td>
-		<td><b><?=_("Name")?></b></td>
-		<td><b><?=_("Speed dial")?></b></td>
+		<td><b><?php _("Number")?></b></td>
+		<td><b><?php _("Name")?></b></td>
+		<td><b><?php _("Speed dial")?></b></td>
 		<td>&nbsp;</td>
 		<td>&nbsp;</td>
 	</tr>
@@ -131,7 +136,7 @@
 
 </table>
 
-<?
+<?php
 }
 ?>
 

Modified: freepbx-modules/trunk/modules/phpagiconf/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/phpagiconf/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/phpagiconf/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/phpagiconf/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -3,7 +3,10 @@
 function phpagiconf_gen_conf() {
 	global $active_modules;
 
-	$file = "/tmp/phpagi_".rand().".conf";
+	// create the tmp file in the same dir
+	// fixes ticket:1910
+	$file = "/etc/asterisk/phpagi_".rand().".conf";
+
 	$data = phpagiconf_get();
 	$content = "[phpagi]\n";
 	$content .= "debug=".($data['debug']?'true':'false')."\n";

Modified: freepbx-modules/trunk/modules/phpagiconf/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/phpagiconf/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/phpagiconf/module.xml (original)
+++ freepbx-modules/trunk/modules/phpagiconf/module.xml Mon Apr  7 13:18:05 2008
@@ -1,17 +1,21 @@
 <module>
 	<rawname>phpagiconf</rawname>
 	<name>PHPAGI Config</name>
-	<version>1.1</version>
+	<version>1.2.2</version>
 	<type>tool</type>
-	<category>Config</category>
+	<category>System Administration</category>
 	<menuitems>
 		<phpagiconf>PHPAGI Config</phpagiconf>
 	</menuitems>
 	<depends>
 		<module>manager ge1.0.4</module>
 	</depends> 
-	<changelog>*1.1* Removed old dependancy checking code, first 2.2 release</changelog>
-	<location>release//2.2/phpagiconf-1.0.tgz</location>
-	<md5sum>d1e9128ba20fc1e08d397f29f7bf2737</md5sum>
-	<info>http://freepbx.org/wiki/phpagiconf</info>
+	<changelog>
+		*1.2.2* Changed categories
+		*1.2.1* Fixed javascript error, removed unused script, bump for rc1
+		*1.2* Create tmp files in /etc/asterisk, fixes ticket:1910
+		*1.1* Removed old dependancy checking code, first 2.2 release
+	</changelog>
+	<location>release/2.3/phpagiconf-1.2.1.tgz</location>
+	<md5sum>251deda6ef264817818f6c756b56b6b3</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/phpagiconf/page.phpagiconf.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/phpagiconf/page.phpagiconf.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/phpagiconf/page.phpagiconf.php (original)
+++ freepbx-modules/trunk/modules/phpagiconf/page.phpagiconf.php Mon Apr  7 13:18:05 2008
@@ -69,7 +69,7 @@
 }
 ?>
 	<h2><?php echo _("PHPAGI Config:"); ?></h2>
-	<form autocomplete="on" name="editAGIConf" action="config.php?type=tool&amp;display=phpagiconf" method="post" onsubmit="return editAGIConf_submit();">
+	<form autocomplete="on" name="editAGIConf" action="config.php?type=tool&amp;display=phpagiconf" method="post">
 	<input type="hidden" name="display" value="<?php echo $dispnum?>">
 	<input type="hidden" name="action" value="<?php echo (isset($thisConfig) ? 'edit' : 'add') ?>">
 	<table>
@@ -141,26 +141,5 @@
 	<tr><td colspan="2"><br><h6><input name="Submit" type="submit" value="<?php echo _("Submit Changes") ?>"></h6></td></tr>
 
 	</table>
-<script language="javascript">
-<!--
-
-var theForm = document.editAGIConf;
-
-if (theForm.description.value == "") {
-	theForm.name.focus();
-} else {
-	theForm.festtext.focus();
-}
-
-function editAGIConf_submit()
-{
-/*
- * TODO: Check input
-*/
-	return true;
-}
-
-//-->
-</script>
 </form>
 </div>

Modified: freepbx-modules/trunk/modules/phpinfo/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/phpinfo/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/phpinfo/module.xml (original)
+++ freepbx-modules/trunk/modules/phpinfo/module.xml Mon Apr  7 13:18:05 2008
@@ -1,13 +1,16 @@
 <module>
 	<rawname>phpinfo</rawname>
 	<name>PHP Info</name>
-	<version>1.0</version>
+	<version>1.1.0.1</version>
+	<changelog>
+		*1.1.0.1* bump for rc1
+		*1.1.0* #1442 remove access problem and iframe
+	</changelog>
 	<type>tool</type>
-	<category>Basic</category>
+	<category>System Administration</category>
 	<menuitems>
 		<phpinfo>PHP Info</phpinfo>
 	</menuitems>
-	<location>release/phpinfo-1.0.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-phpinfo</info>
-	<md5sum>4d779d78f8a2770dbb733eff7c9896c1</md5sum>
+	<location>release/2.3/phpinfo-1.1.0.tgz</location>
+	<md5sum>c9dc164d56ce7121480f6e39a34e249d</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/phpinfo/page.phpinfo.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/phpinfo/page.phpinfo.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/phpinfo/page.phpinfo.php (original)
+++ freepbx-modules/trunk/modules/phpinfo/page.phpinfo.php Mon Apr  7 13:18:05 2008
@@ -1,3 +1,7 @@
-<iframe width=100% height=1000px src=modules/phpinfo/phpinfo.inc.php>
-</iframe>
-
+</div>
+<div class="content">
+<br><br>
+<?php
+	phpinfo();
+?>
+</div>

Modified: freepbx-modules/trunk/modules/pinsets/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/pinsets/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/pinsets/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/pinsets/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -91,7 +91,7 @@
 									$extension = str_replace('|','',$rt);
 									// If there are any wildcards in there, add a _ to the start
 									if (preg_match("/\.|z|x|\[|\]/i", $extension)) { $extension = "_".$extension; }
-									$ext->splice($context, $extension, 0, new ext_macro('pinsets', $thisitem['pinsets_id'].'|'.$thisitem['addtocdr']));
+									$ext->splice($context, $extension, 0, new ext_macro('pinsets', $thisitem['pinsets_id'].','.$thisitem['addtocdr']));
 								}						
 								
 							}

Modified: freepbx-modules/trunk/modules/pinsets/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/pinsets/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/pinsets/install.php (original)
+++ freepbx-modules/trunk/modules/pinsets/install.php Mon Apr  7 13:18:05 2008
@@ -1,4 +1,22 @@
 <?php
-// There is no way to delete a file supplied with modules.
-// This is overwriting the existing file
+
+global $db;
+global $amp_conf;
+
+$autoincrement = (($amp_conf["AMPDBENGINE"] == "sqlite") || ($amp_conf["AMPDBENGINE"] == "sqlite3")) ? "AUTOINCREMENT":"AUTO_INCREMENT";
+
+$sql = "CREATE TABLE IF NOT EXISTS pinsets ( 
+	pinsets_id INTEGER NOT NULL  PRIMARY KEY $autoincrement, 
+	passwords LONGTEXT, 
+	description VARCHAR( 50 ) , 
+	addtocdr TINYINT( 1 ) , 
+	deptname VARCHAR( 50 ) , 
+	used_by VARCHAR( 255 )
+)";
+
+$check = $db->query($sql);
+if(DB::IsError($check)) {
+        die_freepbx("Can not create `pinsets` table\n");
+}
+
 ?>

Modified: freepbx-modules/trunk/modules/pinsets/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/pinsets/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/pinsets/install.sql (original)
+++ freepbx-modules/trunk/modules/pinsets/install.sql Mon Apr  7 13:18:05 2008
@@ -1,1 +1,1 @@
-CREATE TABLE IF NOT EXISTS pinsets ( pinsets_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY , passwords LONGTEXT, description VARCHAR( 50 ) , addtocdr TINYINT( 1 ) , deptname VARCHAR( 50 ) , used_by VARCHAR( 255 ));
+-- empty file, because of http://freepbx.org/trac/ticket/1277

Modified: freepbx-modules/trunk/modules/pinsets/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/pinsets/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/pinsets/module.xml (original)
+++ freepbx-modules/trunk/modules/pinsets/module.xml Mon Apr  7 13:18:05 2008
@@ -1,21 +1,22 @@
 <module>
 	<rawname>pinsets</rawname>
 	<name>PIN Sets</name>
-	<version>1.1.2</version>
+	<version>1.2.2.2</version>
 	<type>setup</type>
 	<category>Internal Options &amp; Configuration</category>
 	<description>Allow creation of lists of PINs (numbers for passwords) that can be used by other modules (eg, trunks).</description>
 	<changelog>
-		*1.1.2* Put None label in menu hook
-		*1.1.1* #1770 added proper uninstall
-		*1.1* Add naftali5's fix for pinsets being lost when routes are moved.
-		*1.0.12* Add he_IL translation
+		*1.2.2.2* #2172 deprecated use of |
+		*1.2.2.1* bump for rc1
+		*1.2.2* Put None label in menu hook
+		*1.2.1* #1770 added proper uninstall
+		*1.2* Add SQLite3 support, fixes http://freepbx.org/trac/ticket/1778
+		*1.1* Add he_IL translation, add naftali5's fixes where pinsets were being lost when moved around.
 		*1.0.11* Stop potential error where a random pinset is appearing when creating a new trunk
 	</changelog>
 	<menuitems>
 		<pinsets>PIN Sets</pinsets>
 	</menuitems>
-	<info>http://aussievoip.com.au/wiki/freePBX-PinSets</info>
-	<location>release/2.2/pinsets-1.1.1.tgz</location>
-	<md5sum>a965de5a91c828ad4b447d19ddc5e049</md5sum>
+	<location>release/2.3/pinsets-1.2.2.1.tgz</location>
+	<md5sum>895f85d305d2084c244fa92ee76ee42d</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/printextensions/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/printextensions/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/printextensions/module.xml (original)
+++ freepbx-modules/trunk/modules/printextensions/module.xml Mon Apr  7 13:18:05 2008
@@ -1,7 +1,7 @@
 <module>
 	<rawname>printextensions</rawname>
 	<name>Print Extensions</name>
-	<version>1.3.1</version>
+	<version>1.3.2</version>
 	<type>tool</type>
 	<category>Third Party Addon</category>
 	<description>Creates a printable list of names and extension numbers</description>
@@ -9,9 +9,9 @@
 		<printextensions>Print Extensions</printextensions>
 	</menuitems>
 	<changelog>
+		*1.3.2* Fixed uninizialized variable errors, bump for rc1
 		*1.3.1* Add he_IL translation
 	</changelog>
-	<location>release/2.2/printextensions-1.3.0.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-PrintExtensions</info>
-	<md5sum>7a5cee510617e9373eae856f86c4ddb8</md5sum>
+	<location>release/2.3/printextensions-1.3.1.tgz</location>
+	<md5sum>b9252d8e33cd6fc984cea23aa7506a3b</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/printextensions/page.printextensions.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/printextensions/page.printextensions.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/printextensions/page.printextensions.php (original)
+++ freepbx-modules/trunk/modules/printextensions/page.printextensions.php Mon Apr  7 13:18:05 2008
@@ -35,7 +35,7 @@
 
 if (isset($gresults)) {
 		foreach ($gresults as $gresult) {
-			$defined = is_array($set_users) ? (in_array($gresult[0], $set_users) ? "(edit)" : "(add)") : "add";
+			$defined = (isset($set_users) && is_array($set_users)) ? (in_array($gresult[0], $set_users) ? "(edit)" : "(add)") : "add";
 			echo "<tr width=\"250\"><td>".$gresult[1]."</td><td width=\"50\" align=\"right\">".$gresult[0]."</td><td width=\"200\" align=\"right\">".$gresult[2]."</td></tr>";
 		}
 }

Modified: freepbx-modules/trunk/modules/queues/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/queues/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/queues/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/queues/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -75,6 +75,9 @@
 					$options = 't';
 					if ($q['rtone'] == 1)
 						$options .= 'r';
+					if (isset($q['music'])) {
+ 						$ext->add('ext-queues', $exten, '', new ext_setvar('__MOHCLASS', $q['music']));
+					}
 					$agentannounce = (isset($q['agentannounce'])?$q['agentannounce']:'');
 					$ext->add('ext-queues', $exten, '', new ext_queue($exten,$options,'',$agentannounce,$q['maxwait']));
  
@@ -131,12 +134,11 @@
 
 function queues_add($account,$name,$password,$prefix,$goto,$agentannounce,$members,$joinannounce,$maxwait) {
 	global $db;
-	
+
 	//add to extensions table
-	if (!empty($agentannounce) && $agentannounce != 'None')
-		$agentannounce="$agentannounce";
-	else
+	if (empty($agentannounce) || $agentannounce == 'None') {
 		$agentannounce="";
+	}
 
 	$addarray = array('ext-queues',$account,'1','Answer',''.'','','0');
 	legacy_extensions_add($addarray);
@@ -148,7 +150,7 @@
 		$addarray = array('ext-queues',$account,'4','Playback',$joinannounce,'','0');
 		legacy_extensions_add($addarray);
 	}
-	$addarray = array('ext-queues',$account,'5','Queue',$account.'|t||'.$agentannounce.'|'.$maxwait,$name,'0');
+	$addarray = array('ext-queues',$account,'5','Queue',$account.',t,,'.$agentannounce.','.$maxwait,$name,'0');
 	legacy_extensions_add($addarray);
 	$addarray = array('ext-queues',$account.'*','1','Macro','agent-add,'.$account.','.$password,'','0');
 	legacy_extensions_add($addarray);
@@ -160,15 +162,15 @@
 	legacy_extensions_add($addarray);
 	//setGoto($account,'ext-queues','6',$goto,0);
 	// Announce Menu?
+	$qpannounce = '';
 	if ($_REQUEST['announcemenu']=='none') {
-		$qthanku = 'queue-thankyou';
 		$context = '';
 	} else {
 		$arr = (ivr_get_details($_REQUEST['announcemenu']));
 		if( isset($arr['announcement']) && !empty($arr['announcement']) ) {
-			$qthanku = $arr['announcement'];
+			$qpannounce = $arr['announcement'];
 		} else {
-			$qthanku = '';
+			$qthanku = 'silence/1';
 		}
 		$context = "ivr-".$_REQUEST['announcemenu'];
 	}
@@ -181,24 +183,28 @@
 		array($account,'joinempty',($_REQUEST['joinempty'])?$_REQUEST['joinempty']:'yes',0),
 		array($account,'leavewhenempty',($_REQUEST['leavewhenempty'])?$_REQUEST['leavewhenempty']:'no',0),
 		array($account,'strategy',($_REQUEST['strategy'])?$_REQUEST['strategy']:'ringall',0),
-		array($account,'timeout',($_REQUEST['timeout'])?$_REQUEST['timeout']:'15',0),
+		array($account,'timeout',(isset($_REQUEST['timeout']))?$_REQUEST['timeout']:'15',0),
 		array($account,'retry',($_REQUEST['retry'])?$_REQUEST['retry']:'5',0),
 		array($account,'wrapuptime',($_REQUEST['wrapuptime'])?$_REQUEST['wrapuptime']:'0',0),
 		//array($account,'agentannounce',($_REQUEST['agentannounce'])?$_REQUEST['agentannounce']:'None'),
 		array($account,'announce-frequency',($_REQUEST['announcefreq'])?$_REQUEST['announcefreq']:'0',0),
 		array($account,'announce-holdtime',($_REQUEST['announceholdtime'])?$_REQUEST['announceholdtime']:'no',0),
-		array($account,'queue-youarenext',($_REQUEST['announceposition']=='no')?'':'queue-youarenext',0),  //if no, play no sound
-		array($account,'queue-thereare',($_REQUEST['announceposition']=='no')?'':'queue-thereare',0),  //if no, play no sound
-		array($account,'queue-callswaiting',($_REQUEST['announceposition']=='no')?'':'queue-callswaiting',0),  //if no, play no sound
-		array($account,'queue-thankyou',$qthanku,0),
+		array($account,'queue-youarenext',($_REQUEST['announceposition']=='no')?'silence/1':'queue-youarenext',0),  //if no, play no sound
+		array($account,'queue-thereare',($_REQUEST['announceposition']=='no')?'silence/1':'queue-thereare',0),  //if no, play no sound
+		array($account,'queue-callswaiting',($_REQUEST['announceposition']=='no')?'silence/1':'queue-callswaiting',0),  //if no, play no sound
+		array($account,'queue-thankyou',($_REQUEST['announceposition']=='no')?'':'queue-thankyou',0),  //if no, play no sound
+		array($account,'periodic-announce',$qpannounce,0), //periodic breakout IVR recording to play back
+		array($account,'periodic-announce-frequency',($_REQUEST['pannouncefreq'])?$_REQUEST['pannouncefreq']:'0',0),
 		array($account,'context',$context,0), 
 		array($account,'monitor-format',($_REQUEST['monitor-format'])?$_REQUEST['monitor-format']:'',0),
 		array($account,'monitor-join','yes',0),
-		array($account,'music',($_REQUEST['music'])?$_REQUEST['music']:'default',0),
 		array($account,'rtone',($_REQUEST['rtone'])?$_REQUEST['rtone']:0,0),
 		array($account,'eventwhencalled',($_REQUEST['eventwhencalled'])?$_REQUEST['eventwhencalled']:'no',0),
 		array($account,'eventmemberstatus',($_REQUEST['eventmemberstatus'])?$_REQUEST['eventmemberstatus']:'no',0));
 
+		if ($_REQUEST['music'] != 'inherit') {
+			$fields[] = array($account,'music',($_REQUEST['music'])?$_REQUEST['music']:'default',0);
+		}
 
 	//there can be multiple members
 	if (isset($members)) {
@@ -212,7 +218,7 @@
     $compiled = $db->prepare('INSERT INTO queues (id, keyword, data, flags) values (?,?,?,?)');
 	$result = $db->executeMultiple($compiled,$fields);
     if(DB::IsError($result)) {
-        die($result->getMessage()."<br><br>error adding to queues table");	
+        die_freepbx($result->getMessage()."<br><br>error adding to queues table");	
     }
 }
 
@@ -226,7 +232,7 @@
 	$sql = "DELETE FROM queues WHERE id = '$account'";
     $result = $db->query($sql);
     if(DB::IsError($result)) {
-        die($result->getMessage().$sql);
+        die_freepbx($result->getMessage().$sql);
     }
 
 }
@@ -269,10 +275,10 @@
 	$results['member'] = $db->getCol($sql);
 	
 	//queues.php looks for 'announcemenu', which is the same a context
-	$results['announcemenu'] = 	$results['context'];
+	$results['announcemenu'] = 	isset($results['context']) ? $results['context']:'';
 	
 	//if 'queue-youarenext=queue-youarenext', then assume we want to announce position
-	if($results['queue-youarenext'] == 'queue-youarenext') 
+	if(isset($results['queue-youarenext']) && $results['queue-youarenext'] == 'queue-youarenext') 
 		$results['announce-position'] = 'yes';
 	else
 		$results['announce-position'] = 'no';
@@ -284,7 +290,7 @@
 		} else {
 			$results['eventmemberstatus'] = 'yes';
 		}
-	} else {
+	} elseif (!isset($results['eventmemberstatus'])){
 		$results['eventmemberstatus'] = 'no';
 	}
 
@@ -297,7 +303,7 @@
 	//get max wait time from Queue command
 	$sql = "SELECT args,descr FROM extensions WHERE extension = '$account' AND context = 'ext-queues' AND application = 'Queue'";
 	list($args, $descr) = $db->getRow($sql);
-	$maxwait = explode('|',$args);  //in table like queuenum|t|||maxwait
+	$maxwait = explode(',',$args);  //in table like queuenum,t,,,maxwait
 	$results['agentannounce'] = $maxwait[3];
 	$results['maxwait'] = $maxwait[4];
 	$results['name'] = $descr;
@@ -313,7 +319,7 @@
 	$results['password'] = $password[2];
 	
 	//get the failover destination (desc=jump)
-	$sql = "SELECT args FROM extensions WHERE extension = '".$account."' AND descr = 'jump'";
+	$sql = "SELECT args FROM extensions WHERE extension = '".$account."' AND descr = 'jump' AND context = 'ext-queues'";
 	list($args) = $db->getRow($sql);
 	$results['goto'] = $args; 
 

Added: freepbx-modules/trunk/modules/queues/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/queues/install.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/queues/install.php (added)
+++ freepbx-modules/trunk/modules/queues/install.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,42 @@
+<?php
+
+global $db;
+global $amp_conf;
+
+$results = array();
+$sql = "SELECT args, extension, priority FROM extensions WHERE context = 'ext-queues' AND descr = 'jump'";
+$results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
+if (!DB::IsError($results)) { // error - table must not be there
+	foreach ($results as $result) {
+		$old_dest  = $result['args'];
+		$extension = $result['extension'];
+		$priority  = $result['priority'];
+
+		$new_dest = merge_ext_followme(trim($old_dest));
+		if ($new_dest != $old_dest) {
+			$sql = "UPDATE extensions SET args = '$new_dest' WHERE extension = '$extension' AND priority = '$priority' AND context = 'ext-queues' AND descr = 'jump' AND args = '$old_dest'";
+			$results = $db->query($sql);
+			if(DB::IsError($results)) {
+				die_freepbx($results->getMessage());
+			}
+		}
+	}
+}
+
+// Version 2.2.11 change (#1659)
+//
+$results = $db->query("ALTER TABLE `queues` CHANGE `id` `id` VARCHAR( 45 ) NOT NULL DEFAULT '-1'");
+if(DB::IsError($results)) {
+	echo $results->getMessage();
+	return false;
+}
+
+// Version 2.2.13 change (#2277)
+//
+$results = $db->query("ALTER TABLE `queues` CHANGE `keyword` `keyword` VARCHAR( 30 ) NOT NULL");
+if(DB::IsError($results)) {
+	echo $results->getMessage();
+	return false;
+}
+
+?>

Modified: freepbx-modules/trunk/modules/queues/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/queues/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/queues/module.xml (original)
+++ freepbx-modules/trunk/modules/queues/module.xml Mon Apr  7 13:18:05 2008
@@ -1,31 +1,43 @@
 <module>
 	<rawname>queues</rawname>
 	<name>Queues</name>
-	<version>2.2.10.3</version>
+	<version>2.2.13.7</version>
 	<type>setup</type>
 	<category>Inbound Call Control</category>
 	<description>
 		Creates a queue where calls are placed on hold and answered on a first-in, first-out basis. Many options are available, including ring strategy for agents, caller announcements, max wait times, etc. 
 	</description>
 	<changelog>
+		*2.2.13.7* #2636 Queues Options member status allways show No
+		*2.2.13.6* #2605 IVR breakout select box picking wrong IVR
+		*2.2.13.5* #2528 add context = 'ext-queues' when getting destination statement
+		*2.2.13.4* initialize qpannounce, may cause queue db errors with IVR breakouts that have no sound file
+		*2.2.13.3* Agent Timeout 0 makes results in default, but should be Unlimited fixed
+		*2.2.13.2* #2313 fix error introduced by #2172, Agent Announce not being saved
+		*2.2.13.1* #2172 deprecated use of |, #2193 hard coded moh path
+		*2.2.13* #2277 fix periodic announce message and hold time
+		*2.2.12.2* bump for rc1
+		*2.2.12.1* #2222 fixed syntax error
+		*2.2.12* #2222 replace defaults announcements with silence to prevent Asterisk 1.4 from crashing
+		*2.2.11* #2185 provide inherit option for MoH, to use what ever is in the channel and add MOHCLASS channel variable, #1659 allow queue 0
 		*2.2.10.3* #2156 fix select box to deal with language translation properly
 		*2.2.10.2* #2057 don't strip CID prefix if no prefix is being added
+		*2.2.10.1* merge findmefollow/core extension destinations if any
 		*2.2.10* Changed chained CID prefixes to be handled the same as ringgroup and followme, also fixed #1965
 		*2.2.9* Replaced deprecated CALLERIDNAME and TIMSTAMP variables with the current and future supported versions
 		*2.2.8.1* Updated tootip to warn about agents.conf (unsupported and know issues) and warn about penalties (broken in asterisk)
 		*2.2.8* Fixed typo in 2.2.7
 		*2.2.7* Fixed eventmemberstatus #1635
 		*2.2.6* Add he_IL translation
-		*2.2.5* Added BLKVM DB tree to fix inability to transfer a received call to another user, and make NODEST stuff work overall
-		*2.2.4* Change _NODEST to __NODEST for some scenarios that require infinite inheritance
-		*2.2.3* Updated for freepbx 2.2.0rc2
+		*2.2.5* Change goto_indicateN to gotoN
+		*2.2.4* Added BLKVM DB tree to fix inability to transfer a received call to another user, and make NODEST stuff work overall
+		*2.2.3* Change _NODEST to __NODEST for some scenarios that require infinite inheritance
 		*2.2.2* Disallow Queue 0 (#1487)
 		*2.2.1* Add NODEST to tell children NOT to go to destinations (like voicemail or other) - helps with followme in a queue
 		*2.2* First release for FreePBX 2.2 - Fixed compatibility issue with new UI</changelog>
 	<menuitems>
 		<queues>Queues</queues>
 	</menuitems>
-	<location>release/2.2/queues-2.2.10.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Queues</info>
-	<md5sum>7c577e3e60d3ee571edc856cd985750b</md5sum>
+	<location>release/2.3/queues-2.2.13.6.tgz</location>
+	<md5sum>bb64f26b354c38824cc9fa974e96a77b</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/queues/page.queues.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/queues/page.queues.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/queues/page.queues.php (original)
+++ freepbx-modules/trunk/modules/queues/page.queues.php Mon Apr  7 13:18:05 2008
@@ -1,4 +1,4 @@
-<?php /* $Id: page.queues.php 4571 2007-07-28 01:58:07Z p_lindheimer $ */
+<?php /* $Id: page.queues.php 5573 2008-01-12 18:36:56Z p_lindheimer $ */
 //Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
 //
 //This program is free software; you can redistribute it and/or
@@ -151,16 +151,17 @@
 	<h2><?php echo _("Add Queue"); ?></h2>
 <?php } ?>
 
-<?php		if ($extdisplay){ ?>
+<?php		if ($extdisplay != ''){ ?>
+
 	<p><?php echo $delButton ?></p>
 <?php		} ?>
 	<form autocomplete="off" name="editQ" action="<?php $_SERVER['PHP_SELF'] ?>" method="post">
 	<input type="hidden" name="display" value="<?php echo $dispnum?>">
-	<input type="hidden" name="action" value="<?php echo ($extdisplay ? 'edit' : 'add') ?>">
+	<input type="hidden" name="action" value="<?php echo (($extdisplay != '') ? 'edit' : 'add') ?>">
 	<table>
 	<tr><td colspan="2"><h5><?php echo ($extdisplay ? _("Edit Queue") : _("Add Queue")) ?><hr></h5></td></tr>
 	<tr>
-<?php		if ($extdisplay){ ?>
+<?php		if ($extdisplay != ''){ ?>
 		<input type="hidden" name="account" value="<?php echo $extdisplay; ?>">
 <?php		} else { ?>
 		<td><a href="#" class="info"><?php echo _("queue number:")?><span><?php echo _("Use this number to dial into the queue, or transfer callers to this number to put them into the queue.<br><br>Agents will dial this queue number plus * to log onto the queue, and this queue number plus ** to log out of the queue.<br><br>For example, if the queue number is 123:<br><br><b>123* = log in<br>123** = log out</b>")?></span></a></td>
@@ -221,12 +222,13 @@
 
 <?php if(function_exists('music_list')) { //only include if music module is enabled?>
 	<tr>
-		<td><a href="#" class="info"><?php echo _("Hold Music Category:")?><span><?php echo _("Music (or Commercial) played to the caller while they wait in line for an available agent.<br><br>  This music is defined in the \"On Hold Music\" Menu to the left.")?></span></a></td>
+		<td><a href="#" class="info"><?php echo _("Music on Hold Class:")?><span><?php echo _("Music (or Commercial) played to the caller while they wait in line for an available agent. Choose \"inherit\" if you want the MoH class to be what is currently selected, such as by the inbound route.<br><br>  This music is defined in the \"Music on Hold\" Menu to the left.")?></span></a></td>
 		<td>
 			<select name="music"/>
 			<?php
-				$tresults = music_list("/var/lib/asterisk/mohmp3");
-				$default = (isset($music) ? $music : 'default');
+				$tresults = music_list($amp_conf['ASTVARLIBDIR']."/mohmp3");
+				array_unshift($tresults,'inherit');
+				$default = (isset($music) ? $music : 'inherit');
 				if (isset($tresults)) {
 					foreach ($tresults as $tresult) {
 						$searchvalue="$tresult";	
@@ -327,12 +329,13 @@
 		</td>
 	</tr>
 	<tr>
-		<td><a href="#" class="info"><?php echo _("agent timeout:")?><span><?php echo _("The number of seconds an agents phone can ring before we consider it a timeout.")?></span></a></td>
+		<td><a href="#" class="info"><?php echo _("agent timeout:")?><span><?php echo _("The number of seconds an agent's phone can ring before we consider it a timeout. Unlimited or other timeout values may still be limited by system ringtime or individual extension defaults.")?></span></a></td>
 		<td>
 			<select name="timeout"/>
 			<?php
 				$default = (isset($timeout) ? $timeout : 15);
-				for ($i=0; $i <= 60; $i++) {
+				echo '<option value="0" '.(0 == $default ? 'SELECTED' : '').'>'."Unlimited".'</option>';
+				for ($i=1; $i <= 60; $i++) {
 					echo '<option value="'.$i.'" '.($i == $default ? 'SELECTED' : '').'>'.queues_timeString($i,true).'</option>';
 				}
 			?>		
@@ -407,9 +410,9 @@
 			</select>
 		</td>
 	</tr>
-	<tr><td colspan="2"><br><h5><?php echo _("Caller Announcements")?><hr></h5></td></tr>
-	<tr>
-		<td><a href="#" class="info"><?php echo _("Frequency:")?><span><?php echo _("How often to announce queue position, estimated holdtime, and/or voice menu to the caller (0 to Disable Announcements).")?></span></a></td>
+	<tr><td colspan="2"><br><h5><?php echo _("Caller Position Announcements")?><hr></h5></td></tr>
+	<tr>
+		<td><a href="#" class="info"><?php echo _("Frequency:")?><span><?php echo _("How often to announce queue position and estimated holdtime (0 to Disable Announcements).")?></span></a></td>
 		<td>
 			<select name="announcefreq"/>
 			<?php
@@ -421,7 +424,7 @@
 			</select>		
 		</td>
 	</tr>
-	<tr>
+<tr>
 		<td><a href="#" class="info"><?php echo _("Announce Position:")?><span><?php echo _("Announce position of caller in the queue?")?></span></a></td>
 		<td>
 			<select name="announceposition"/>
@@ -446,12 +449,16 @@
 			</select>		
 		</td>
 	</tr>
+
+<tr><td colspan="2"><br><h5><?php echo _("Periodic Announcements")?><hr></h5></td></tr>
+
+	
 <?php if(function_exists('ivr_list')) { //only include if IVR module is enabled ?>
 	<tr>
-		<td><a href="#" class="info"><?php echo _("Voice Menu:")?><span> <?php echo _("After announcing Position and/or Hold Time, you can optionally present an existing Digital Receptionist Voice Menu.<br><br>This voicemenu must only contain single-digit 'dialed options'.")?> </span></a></td>
+		<td><a href="#" class="info"><?php echo _("IVR Break Out Menu:")?><span> <?php echo _("You can optionally present an existing IVR as a 'break out' menu.<br><br>This IVR must only contain single-digit 'dialed options'. The Recording set for the IVR will be played at intervals specified in 'Repeat Frequency', below.")?></span></a></td>
 		<td>
 			<select name="announcemenu">
-			<?php // setting this will override the sound file queue-thankyou, and set the context= option
+			<?php // setting this will set the context= option
 			$default = (isset($announcemenu) ? $announcemenu : "none");
 			
 			echo '<option value=none '.($default == "none" ? 'SELECTED' : '').'>'._("None").'</option>';
@@ -463,7 +470,7 @@
 				foreach ($unique_aas as $unique_aa) {
 					$menu_id = $unique_aa['ivr_id'];
 					$menu_name = $unique_aa['displayname'];
-					echo '<option value="'.$menu_id.'" '.(strpos($default,$menu_id) === false ? '' : 'SELECTED').'>'.($menu_name ? $menu_name : _("Menu ID ").$menu_id);
+					echo '<option value="'.$menu_id.'" '.((strcasecmp($default,"ivr-".$menu_id) != 0) ? '' : 'SELECTED').'>'.($menu_name ? $menu_name : _("Menu ID ").$menu_id);
 				}
 			}
 		
@@ -472,6 +479,20 @@
 		</td>
 	</tr>
 	
+<tr>
+		<td><a href="#" class="info"><?php echo _("Repeat Frequency:")?><span><?php echo _("How often to announce a voice menu to the caller (0 to Disable Announcements).")?></span></a></td>
+		<td>
+			<select name="pannouncefreq"/>
+			<?php
+				$default = (isset($thisQ['periodic-announce-frequency']) ? $thisQ['periodic-announce-frequency'] : 0);
+				for ($i=0; $i <= 1200; $i+=15) {
+					echo '<option value="'.$i.'" '.($i == $default ? 'SELECTED' : '').'>'.queues_timeString($i,true).'</option>';
+				}
+			?>		
+			</select>		
+		</td>
+	</tr>
+
 <?php } else {
 	echo "<input type=\"hidden\" name=\"announcemenu\" value=\"none\">";
 }
@@ -536,26 +557,9 @@
                 whichitem++;
         }
 
-        var gotoType = theForm.elements[ "goto0" ].value;
-        if (gotoType == 'custom') {
-                var gotoVal = theForm.elements[ "custom0"].value;
-                if (gotoVal.indexOf('custom') == -1) {
-                        bad = "true";
-						<?php echo "alert('"._("Custom Goto contexts must contain the string \"custom\".  ie: custom-app,s,1")."')"?>;
-                }
-        }
-
         $account = theForm.account.value;
         if ($account == "") {
                 <?php echo "alert('"._("Queue Number must not be blank")."')"?>;
-                bad="true";
-        }
-	else if ($account == "0") {
-                <?php echo "alert('"._("Queue Number can not be 0")."')"?>;
-                bad="true";
-        }
-        else if (($account.indexOf('0') == 0) && ($account.length > 1)) {
-                <?php echo "alert('"._("Queue numbers with more than one digit cannot begin with 0")."')"?>;
                 bad="true";
         }
 

Added: freepbx-modules/trunk/modules/recordings/audio.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/recordings/audio.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/recordings/audio.php (added)
+++ freepbx-modules/trunk/modules/recordings/audio.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * plays recording file
+ */
+
+if (isset($_GET['recording'])) {
+
+  include_once("crypt.php");
+
+  $REC_CRYPT_PASSWORD = (isset($_REQUEST['cryptpass']) && trim($_REQUEST['cryptpass']) != "")?trim($_REQUEST['cryptpass']):'moufdsuu3nma0';
+
+  $crypt = new Crypt();
+
+  $opath = $_GET['recording'];
+  $path = $crypt->decrypt($opath,urldecode($REC_CRYPT_PASSWORD));
+  $path=$opath;
+
+  // strip ".." from path for security
+  $path = preg_replace('/\.\./','',$path);
+  
+  // See if the file exists, otherwise check for extensions
+  if (is_file("$path.wav")) { $path="$path.wav"; }
+  elseif (is_file("$path.Wav")) { $path="$path.Wav"; }
+  elseif (is_file("$path.WAV")) { $path="$path.WAV"; }
+  elseif (is_file("$path.mp3")) { $path="$path.mp3"; }
+  elseif (is_file("$path.gsm")) { $path="$path.gsm"; }
+  elseif (!is_file($path)) { die("<b>404 File not found!: $opath </b>"); }
+
+  // Gather relevent info about file
+  $size = filesize($path);
+  $name = basename($path);
+  $extension = strtolower(substr(strrchr($name,"."),1));
+
+  // This will set the Content-Type to the appropriate setting for the file
+  $ctype ='';
+  switch( $extension ) {
+    case "mp3": $ctype="audio/mpeg"; break;
+    case "wav": $ctype="audio/x-wav"; break;
+    case "Wav": $ctype="audio/x-wav"; break;
+    case "WAV": $ctype="audio/x-wav"; break;
+    case "gsm": $ctype="audio/x-gsm"; break;
+
+    // not downloadable
+    default: die_freepbx("<b>404 File not found! foo</b>"); break ;
+  }
+
+  // need to check if file is mislabeled or a liar.
+  $fp=fopen($path, "rb");
+  if ($size && $ctype && $fp) {
+    header("Pragma: public");
+    header("Expires: 0");
+    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
+    header("Cache-Control: public");
+    header("Content-Description: wav file");
+    header("Content-Type: " . $ctype);
+    header("Content-Disposition: attachment; filename=" . $name);
+    header("Content-Transfer-Encoding: binary");
+    header("Content-length: " . $size);
+    fpassthru($fp);
+  } 
+}
+
+?>

Added: freepbx-modules/trunk/modules/recordings/crypt.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/recordings/crypt.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/recordings/crypt.php (added)
+++ freepbx-modules/trunk/modules/recordings/crypt.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,81 @@
+<?php
+
+/*
+ * Allows encrypt and decrypt
+ */
+class Crypt {
+
+  /**
+   * Gets a random value for encryption
+   * - From php.net docs
+   *
+   * @param $iv_len
+   *   length of random variable
+   */
+  function getRndIV($iv_len) {
+
+    $iv = '';
+    while ($iv_len-- > 0) {
+      $iv .= chr(mt_rand() & 0xff);
+    }
+    return $iv;
+  }
+
+  /**
+   * Encrypts string
+   * - From php.net docs
+   *
+   * @param $str
+   *   string to encrypt
+   * @param $salt
+   *   password to use for encryption
+   * @param $iv_len
+   *   length of random number
+   */
+  function encrypt($str, $salt, $iv_len = 16) {
+
+    $str .= "\x13";
+    $n = strlen($str);
+    if ($n % 16) $str .= str_repeat("\0", 16 - ($n % 16));
+    $i = 0;
+    $enc_text = $this->getRndIV($iv_len);
+    $iv = substr($salt ^ $enc_text, 0, 512);
+    while ($i < $n) {
+      $block = substr($str, $i, 16) ^ pack('H*', md5($iv));
+      $enc_text .= $block;
+      $iv = substr($block . $iv, 0, 512) ^ $salt;
+      $i += 16;
+    }
+    return urlencode(base64_encode($enc_text));
+  }
+
+  /**
+   * Decrypts string
+   * - From php.net docs
+   *
+   * @param $enc
+   *   encrypted string to decrypt
+   * @param $salt
+   *   password to use for encryption
+   * @param $iv_len
+   *   length of random number
+   */
+  function decrypt($enc, $salt, $iv_len = 16) {
+
+     $enc = urldecode(base64_decode($enc));
+     $n = strlen($enc);
+     $i = $iv_len;
+     $str = '';
+     $iv = substr($salt ^ substr($enc, 0, $iv_len), 0, 512);
+     while ($i < $n) {
+         $block = substr($enc, $i, 16);
+         $str .= $block ^ pack('H*', md5($iv));
+         $iv = substr($block . $iv, 0, 512) ^ $salt;
+         $i += 16;
+     }
+     return preg_replace('/\\x13\\x00*$/', '', $str);
+  }
+}
+
+
+?>

Modified: freepbx-modules/trunk/modules/recordings/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/recordings/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/recordings/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/recordings/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -149,9 +149,12 @@
 	// del[N] - Delete fid N
 	
 	foreach ($_REQUEST as $key => $val) {
-		$up = strpos($key, "up");
-		$down = strpos($key, "down");
-		$del = strpos($key, "del");
+		if (strpos($key,"_") == 0) {
+	      		$up = strpos($key, "up");
+
+			$down = strpos($key, "down");
+			$del = strpos($key, "del");
+		}
 		if ( $up !== false ) {
 			$up = substr($key, 2);
 			recordings_move_file_up($id, $up);

Added: freepbx-modules/trunk/modules/recordings/images/play.png
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/recordings/images/play.png?rev=5512&op=file
==============================================================================
Binary file - no diff available.

Propchange: freepbx-modules/trunk/modules/recordings/images/play.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: freepbx-modules/trunk/modules/recordings/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/recordings/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/recordings/install.php (original)
+++ freepbx-modules/trunk/modules/recordings/install.php Mon Apr  7 13:18:05 2008
@@ -25,7 +25,7 @@
 $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($result->getDebugInfo());
+        die_freepbx($result->getDebugInfo());
 }
 
 // load up any recordings that might be in the directory
@@ -62,7 +62,7 @@
 $sql = 'ALTER TABLE recordings CHANGE filename filename BLOB';
 $result = $db->query($sql);
 if(DB::IsError($result)) {
-	die($result->getDebugInfo());
+	die_freepbx($result->getDebugInfo());
 }
 
 ?>

Modified: freepbx-modules/trunk/modules/recordings/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/recordings/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/recordings/module.xml (original)
+++ freepbx-modules/trunk/modules/recordings/module.xml Mon Apr  7 13:18:05 2008
@@ -1,26 +1,32 @@
 <module>
 	<rawname>recordings</rawname>
 	<name>Recordings</name>
-	<version>3.3.4.1</version>
+	<version>3.3.5.4</version>
+	<candisable>no</candisable>
+	<canuninstall>no</canuninstall>
 	<type>setup</type>
 	<category>Internal Options &amp; Configuration</category>
 	<description>Creates and manages system recordings, used by many other modules (eg, IVR).</description>
 	<changelog>
-	*3.3.4.1* #2092 can't cannot save/read file fix some errors, better messages
-	*3.3.4* fixed bug not able to save recorded message from *77 featurecode, backported for FreePBX 2.3
-	*3.3.3* #2032 remove recordings as a destination, no purpose (use annoucement module)
-	*3.3.2* Fix mp3 upload bug (#1764)
-	*3.3.1* Fix error where *77/*79 wasn't working.
-	*3.3* Stop assuming that files being uploaded are .wav's, also highlight the correct format for files to be uploaded in.
-	*3.2.4* Add he_IL translation
-	*3.2.3* Fix for possible wrong recording being selected
-	*3.2.2* Fix for PHP5 not picking up ast recording path
-	*3.2.1* Resolved issue with wrong recording being selected when there's more than one encoding of file (eg, foo.wav and foo.gsm)
-	*3.2* First release for FreePBX 2.2 - Fixed compatibility issue with new UI</changelog>
+		*3.3.5.4* #2426 remove non-functioning download link
+		*3.3.5.3* #2409 syntax error in audio.php could cause playback problems
+		*3.3.5.2* #2016 allow amportal.conf AMPLAYKEY override hardcoded crypt key
+		*3.3.5.1* bump for rc1
+		*3.3.5* #2092 can't cannot save/read file fix some errors, better messages
+		*3.3.4* #2032 remove recordings as a destination, no purpose (use annoucement module)
+		*3.3.3* fixed bug not able to save recorded message from *77 featurecode
+		*3.3.2* use urlencode/decode in the crypt functions
+		*3.3.1.1* added candisable = no for module admin, and new play button
+		*3.3.1* Fix mp3 upload bug (#1764)
+		*3.3* Stop assuming that files being uploaded are .wav's, also highlight the correct format for files to be uploaded in.
+		*3.2.4* Add he_IL translation
+		*3.2.3* Fix for possible wrong recording being selected
+		*3.2.2* Fix for PHP5 not picking up ast recording path
+		*3.2.1* Resolved issue with wrong recording being selected when there's more than one encoding of file (eg, foo.wav and foo.gsm)
+		*3.2* First release for FreePBX 2.2 - Fixed compatibility issue with new UI</changelog>
 	<menuitems>
 		<recordings>System Recordings</recordings>
 	</menuitems>
-	<location>release/2.2/recordings-3.3.4.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-SysRec</info>
-	<md5sum>608a7b76f4f74123cb795aff2c51714f</md5sum>
+	<location>release/2.3/recordings-3.3.5.3.tgz</location>
+	<md5sum>1b2afe48ae31f169a6504d1c12468263</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/recordings/page.recordings.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/recordings/page.recordings.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/recordings/page.recordings.php (original)
+++ freepbx-modules/trunk/modules/recordings/page.recordings.php Mon Apr  7 13:18:05 2008
@@ -1,5 +1,5 @@
 <?php 
-/* $Id: page.recordings.php 4576 2007-07-28 05:34:24Z p_lindheimer $ */
+/* $Id: page.recordings.php 4898 2007-08-19 04:53:32Z p_lindheimer $ */
 //Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
 //
 //Re-written by Rob Thomas <xrobau at gmail.com> 20060318.
@@ -31,9 +31,6 @@
 	$dest = "{$usersnum}-";
 }
 
-if (empty($suffix)) { // Ensure that suffix is set to something reasonable
-	$suffix = "wav";
-}
 // get feature codes for diplay purposes
 $fcc = new featurecode('recordings', 'record_save');
 $fc_save = $fcc->getCodeActive();
@@ -241,7 +238,7 @@
 	echo "<a href=config.php?display=recordings&amp;action=delete&amp;usersnum=".urlencode($num);
 	echo "&amp;id=$id>Remove Recording</a> <i style='font-size: x-small'>(Note, does not delete file from computer)</i>";
 	?>
-	<form name="prompt" action="<?php $_SERVER['PHP_SELF'] ?>" method="post" onsubmit="return rec_onsubmit();">
+	<form name="prompt"  action="<?php $_SERVER['PHP_SELF'] ?>" method="post" onsubmit="return rec_onsubmit();">
 	<input type="hidden" name="action" value="edited">
 	<input type="hidden" name="display" value="recordings">
 	<input type="hidden" name="usersnum" value="<?php echo $num ?>">
@@ -266,14 +263,19 @@
 	$files = explode('&', $fn);
 	$counter = 0;
 	$arraymax = count($files)-1;
+	// globals seem to busted in PHP5 define here for now
+	$recordings_astsnd_path = isset($asterisk_conf['astvarlibdir'])?$asterisk_conf['astvarlibdir']:'/var/lib/asterisk';
+	$recordings_astsnd_path .= "/sounds/";
+
 	foreach ($files as $item) {
-		recordings_display_sndfile($item, $counter, $arraymax);
+		recordings_display_sndfile($item, $counter, $arraymax, $recordings_astsnd_path);
 		$counter++;
 	}	
-	recordings_display_sndfile('', $counter, $arraymax);
+	recordings_display_sndfile('', $counter, $arraymax, $recordings_astsnd_path);
 	?>
 	</table>
 	<input name="Submit" type="submit" value="<?php echo _("Save")?>"></h6>
+	<?php recordings_popup_jscript(); ?>	
 	<?php recordings_form_jscript(); ?>	
 	</form>
 	</div>
@@ -312,6 +314,23 @@
         echo "</ul></div>\n";
 }
 
+function recordings_popup_jscript() {
+?>
+        <script language="javascript">
+	<!-- Begin
+	function popUp(URL,optionId) {
+		var selIndex=optionId.selectedIndex
+		var file=optionId.options[selIndex].value
+
+		/*alert(selIndex);*/
+		if (file != "")
+			popup = window.open(URL+file, 'play', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=1,width=320,height=110');
+	}
+	// End -->
+	</script>
+<?php
+}
+
 function recordings_form_jscript() {
 ?>
 	<script language="javascript">
@@ -361,28 +380,48 @@
 <?php
 }
 
-function recordings_display_sndfile($item, $count, $max) {
+function recordings_display_sndfile($item, $count, $max, $astpath) {
+	global $amp_conf;
 	// Note that when using this, it needs a <table> definition around it.
 	$astsnd = isset($asterisk_conf['astvarlibdir'])?$asterisk_conf['astvarlibdir']:'/var/lib/asterisk';
 	$astsnd .= "/sounds/";
 	$sysrecs = recordings_readdir($astsnd, strlen($astsnd)+1);
-	print "<tr><td><select name='sysrec$count'>\n";
+	print "<tr><td><select id='sysrec$count' name='sysrec$count'>\n";
 	echo '<option value=""'.($item == '' ? ' SELECTED' : '')."></option>\n";
 	foreach ($sysrecs as $sr) {
 		echo '<option value="'.$sr.'"'.($sr == $item ? ' SELECTED' : '').">$sr</option>\n";
 	}
 	print "</select></td>\n";
+
+	echo "<td>";
+	$audio=$astpath;
+
+	$REC_CRYPT_PASSWORD = urlencode((isset($amp_conf['AMPPLAYKEY']) && trim($amp_conf['AMPPLAYKEY']) != "")?trim($amp_conf['AMPPLAYKEY']):'moufdsuu3nma0');
+	$recurl="modules/recordings/popup.php?cryptpass=$REC_CRYPT_PASSWORD&recording=$audio";
+
+	echo "<a href='#' type='submit' onClick=\"javascript:popUp('$recurl',document.prompt.sysrec$count); return false;\" input='foo'  >";
+        echo "<img border='0' width='20'  height='20' src='images/play.png' title='Click here to play this recording' />";
+        echo "</img></td>";
+
 	if ($count==0) {
 		 print "<td></td>\n"; 
 	} else {
-		echo '<td><input name="up'.$count.'" type="submit" value="'._("Move Up")."\"></td>\n";
+		echo "<img border='0' width='3' height='11' style='float: none; margin-left: 0px; margin-bottom: 0px;' src='images/blank.gif' />";
+		echo '<td><input name="up'.$count.'" width=10 height=20 border=5  title="Move Up" type="image" src="images/scrollup.gif"  value="'._("Move Up").'"/>';
+		print "</td>\n"; 
+	} if ($count > $max) {
+		print "<td></td>\n"; 
+	} else {
+		echo "<img border='0' width='3' height='11' style='float: none; margin-left: 0px; margin-bottom: 0px;' src='images/blank.gif' />";
+		echo '<td><input name="down'.$count.'" width=10 height=20 border=0 title="Move Down" type="image" src="images/scrolldown.gif"  value="'._("Move Down")."\">\n";
+		echo "<img border='0' width='3' height='11' style='float: none; margin-left: 0px; margin-bottom: 0px;' src='images/blank.gif' />";
+		print "</td>\n"; 
 	}
-	if ($count > $max) {
-		 print "<td></td>\n"; 
-	} else {
-		echo '<td><input name="down'.$count.'" type="submit" value="'._("Move Down")."\"></td>\n";
-	}
-	echo '<td><input name="del'.$count.'" type="submit" value="'._("Delete")."\"></td>\n";
+	echo '<td><input name="del'.$count.'" type="image" border=0 title="Delete" src="images/trash.png" value="'._("Delete")."\">\n";
+	echo "<img border='0' width='9' height='11' style='float: none; margin-left: 0px; margin-bottom: 0px;' src='images/blank.gif' />";
+	echo "<img border='0' width='9' height='11' style='float: none; margin-left: 0px; margin-bottom: 0px;' src='images/blank.gif' />";
+	print "</td>\n"; 
+
 	print "</tr>\n";
 }
 

Added: freepbx-modules/trunk/modules/recordings/popup.css
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/recordings/popup.css?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/recordings/popup.css (added)
+++ freepbx-modules/trunk/modules/recordings/popup.css Mon Apr  7 13:18:05 2008
@@ -1,0 +1,10 @@
+/*
+ * popup
+ */
+
+.popup_download {
+  color: #105D90; 
+  margin: 5px; 
+  font-size: 12px; 
+  text-align: left;
+}

Added: freepbx-modules/trunk/modules/recordings/popup.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/recordings/popup.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/recordings/popup.php (added)
+++ freepbx-modules/trunk/modules/recordings/popup.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * popup window for playing recording
+ */
+
+include_once("crypt.php");
+
+?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<TITLE>FreePBX Recording Review</TITLE>
+		<link rel="stylesheet" href="popup.css" type="text/css">
+		<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+	</head>
+	<body>
+
+<?php
+
+  $REC_CRYPT_PASSWORD = urlencode((isset($_REQUEST['cryptpass']) && trim($_REQUEST['cryptpass']) != "")?trim($_REQUEST['cryptpass']):'moufdsuu3nma0');
+
+  $crypt = new Crypt();
+
+  $file = $crypt->encrypt($_REQUEST['recording'],$REC_CRYPT_PASSWORD);
+  $ufile = $_REQUEST['recording'];
+  $file = $_REQUEST['recording'];
+
+  if (isset($file)) {
+    echo("<br>");
+    echo("<embed src='audio.php?cryptpass=$REC_CRYPT_PASSWORD&recording=$file' width=300, height=20 autoplay=true loop=false></embed><br>");
+    echo("<br><h1 class='popup_download'>playing: $file</h1><br>");
+  }
+?>
+  </body>
+</html>
+

Modified: freepbx-modules/trunk/modules/ringgroups/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/ringgroups/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/ringgroups/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/ringgroups/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -1,4 +1,4 @@
-<?php /* $Id: functions.inc.php 4316 2007-07-07 15:18:24Z p_lindheimer $ */
+<?php /* $Id: functions.inc.php 4638 2007-08-02 20:11:09Z p_lindheimer $ */
 
 // The destinations this module provides
 // returns a associative arrays with keys 'destination' and 'description'
@@ -151,17 +151,17 @@
 	}
 	print_r($extens);
 
-	$sql = "INSERT INTO ringgroups (grpnum, strategy, grptime, grppre, grplist, annmsg, postdest, description, alertinfo, needsconf, remotealert, toolate, ringing) VALUES (".$grpnum.", '".str_replace("'", "''", $strategy)."', ".str_replace("'", "''", $grptime).", '".str_replace("'", "''", $grppre)."', '".str_replace("'", "''", $grplist)."', '".str_replace("'", "''", $annmsg)."', '".str_replace("'", "''", $postdest)."', '".str_replace("'", "''", $desc)."', '".str_replace("'", "''", $alertinfo)."', '$needsconf', '$remotealert', '$toolate', '$ringing')";
+	$sql = "INSERT INTO ringgroups (grpnum, strategy, grptime, grppre, grplist, annmsg, postdest, description, alertinfo, needsconf, remotealert, toolate, ringing) VALUES ('".str_replace("'","''",$grpnum)."', '".str_replace("'", "''", $strategy)."', ".str_replace("'", "''", $grptime).", '".str_replace("'", "''", $grppre)."', '".str_replace("'", "''", $grplist)."', '".str_replace("'", "''", $annmsg)."', '".str_replace("'", "''", $postdest)."', '".str_replace("'", "''", $desc)."', '".str_replace("'", "''", $alertinfo)."', '$needsconf', '$remotealert', '$toolate', '$ringing')";
 	$results = sql($sql);
 	return true;
 }
 
 function ringgroups_del($grpnum) {
-	$results = sql("DELETE FROM ringgroups WHERE grpnum = $grpnum","query");
+	$results = sql("DELETE FROM ringgroups WHERE grpnum = '".str_replace("'","''",$grpnum)."'","query");
 }
 
 function ringgroups_list() {
-	$results = sql("SELECT grpnum, description FROM ringgroups ORDER BY grpnum","getAll",DB_FETCHMODE_ASSOC);
+	$results = sql("SELECT grpnum, description FROM ringgroups ORDER BY CAST(grpnum as UNSIGNED)","getAll",DB_FETCHMODE_ASSOC);
 	foreach ($results as $result) {
 		if (isset($result['grpnum']) && checkRange($result['grpnum'])) {
 			$grps[] = array($result['grpnum'], $result['description']);
@@ -174,7 +174,7 @@
 }
 
 function ringgroups_get($grpnum) {
-	$results = sql("SELECT grpnum, strategy, grptime, grppre, grplist, annmsg, postdest, description, alertinfo, needsconf, remotealert, toolate, ringing FROM ringgroups WHERE grpnum = $grpnum","getRow",DB_FETCHMODE_ASSOC);
+	$results = sql("SELECT grpnum, strategy, grptime, grppre, grplist, annmsg, postdest, description, alertinfo, needsconf, remotealert, toolate, ringing FROM ringgroups WHERE grpnum = '".str_replace("'", "''", $grpnum)."'","getRow",DB_FETCHMODE_ASSOC);
 	return $results;
 }
 ?>

Modified: freepbx-modules/trunk/modules/ringgroups/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/ringgroups/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/ringgroups/install.php (original)
+++ freepbx-modules/trunk/modules/ringgroups/install.php Mon Apr  7 13:18:05 2008
@@ -10,21 +10,21 @@
     $sql = "ALTER TABLE ringgroups ADD description VARCHAR( 35 ) NULL ;";
     $result = $db->query($sql);
     if(DB::IsError($result)) {
-            die($result->getDebugInfo());
+            die_freepbx($result->getDebugInfo());
     }
 
     // update existing groups
     $sql = "UPDATE ringgroups SET description = CONCAT('Ring Group ', grpnum) WHERE description IS NULL ;";
     $result = $db->query($sql);
     if(DB::IsError($result)) {
-            die($result->getDebugInfo());
+            die_freepbx($result->getDebugInfo());
     }
 
 	// make new field required
 	$sql = "ALTER TABLE `ringgroups` CHANGE `description` `description` VARCHAR( 35 ) NOT NULL ;";
     $result = $db->query($sql);
     if(DB::IsError($result)) {
-            die($result->getDebugInfo());
+            die_freepbx($result->getDebugInfo());
     }
 }
 // Version 1.2 upgrade
@@ -35,7 +35,7 @@
     $sql = "ALTER TABLE ringgroups ADD alertinfo VARCHAR( 255 ) NULL ;";
     $result = $db->query($sql);
     if(DB::IsError($result)) {
-            die($result->getDebugInfo());
+            die_freepbx($result->getDebugInfo());
     }
 }
 // increase size for older installs
@@ -48,15 +48,15 @@
 	// add new field
     $sql = "ALTER TABLE ringgroups ADD remotealert VARCHAR( 80 ) NULL ;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 
     $sql = "ALTER TABLE ringgroups ADD needsconf VARCHAR( 10 ) NULL ;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 
     $sql = "ALTER TABLE ringgroups ADD toolate VARCHAR( 80 ) NULL ;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 }
 // Version 2.1 upgrade. Add support for ${DIALOPTS} override, playing MOH
 $sql = "SELECT ringing FROM ringgroups";
@@ -65,8 +65,34 @@
 	// add new field
     $sql = "ALTER TABLE ringgroups ADD ringing VARCHAR( 80 ) NULL ;";
     $result = $db->query($sql);
-    if(DB::IsError($result)) { die($result->getDebugInfo()); }
+    if(DB::IsError($result)) { die_freepbx($result->getDebugInfo()); }
 }
 
+$results = array();
+$sql = "SELECT grpnum, postdest FROM ringgroups";
+$results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
+if (!DB::IsError($results)) { // error - table must not be there
+	foreach ($results as $result) {
+		$old_dest  = $result['postdest'];
+		$grpnum    = $result['grpnum'];
+
+		$new_dest = merge_ext_followme(trim($old_dest));
+		if ($new_dest != $old_dest) {
+			$sql = "UPDATE ringgroups SET postdest = '$new_dest' WHERE grpnum = $grpnum  AND postdest = '$old_dest'";
+			$results = $db->query($sql);
+			if(DB::IsError($results)) {
+				die_freepbx($results->getMessage());
+			}
+		}
+	}
+}
+
+// Version 2.2.16 change (#1961)
+//
+$results = $db->query("ALTER TABLE `ringgroups` CHANGE `grpnum` `grpnum` VARCHAR( 20 ) NOT NULL");
+if(DB::IsError($results)) {
+	echo $results->getMessage();
+	return false;
+}
 
 ?>

Modified: freepbx-modules/trunk/modules/ringgroups/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/ringgroups/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/ringgroups/install.sql (original)
+++ freepbx-modules/trunk/modules/ringgroups/install.sql Mon Apr  7 13:18:05 2008
@@ -1,1 +1,1 @@
-CREATE TABLE IF NOT EXISTS `ringgroups` ( `grpnum` BIGINT( 11 ) NOT NULL , `strategy` VARCHAR( 50 ) NOT NULL , `grptime` SMALLINT NOT NULL , `grppre` VARCHAR( 100 ) NULL , `grplist` VARCHAR( 255 ) NOT NULL , `annmsg` VARCHAR( 255 ) NULL , `postdest` VARCHAR( 255 ) NULL , `description` VARCHAR( 35 ) NOT NULL , `alertinfo` VARCHAR ( 255 ) NULL , remotealert VARCHAR ( 80 ), needsconf VARCHAR ( 10 ), toolate VARCHAR ( 80 ), PRIMARY KEY  (`grpnum`) ) TYPE = MYISAM ; 
+CREATE TABLE IF NOT EXISTS `ringgroups` ( `grpnum` VARCHAR( 20 ) NOT NULL , `strategy` VARCHAR( 50 ) NOT NULL , `grptime` SMALLINT NOT NULL , `grppre` VARCHAR( 100 ) NULL , `grplist` VARCHAR( 255 ) NOT NULL , `annmsg` VARCHAR( 255 ) NULL , `postdest` VARCHAR( 255 ) NULL , `description` VARCHAR( 35 ) NOT NULL , `alertinfo` VARCHAR ( 255 ) NULL , remotealert VARCHAR ( 80 ), needsconf VARCHAR ( 10 ), toolate VARCHAR ( 80 ), PRIMARY KEY  (`grpnum`) ) TYPE = MYISAM ; 

Modified: freepbx-modules/trunk/modules/ringgroups/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/ringgroups/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/ringgroups/module.xml (original)
+++ freepbx-modules/trunk/modules/ringgroups/module.xml Mon Apr  7 13:18:05 2008
@@ -1,17 +1,24 @@
 <module>
 	<rawname>ringgroups</rawname>
 	<name>Ring Groups</name>
-	<version>2.2.15.1</version>
+	<version>2.2.16.2</version>
 	<type>setup</type>
 	<category>Inbound Call Control</category>
 	<description>
 		Creates a group of extensions that all ring together. Extensions can be rung all at once, or in various 'hunt' configurations. Additionally, external numbers are supported, and there is a call confirmation option where the callee has to confirm if they actually want to take the call before the caller is transferred.
 	</description>
 	<changelog>
+		*2.2.16.2* #2193 moh path hardcoded
+		*2.2.16.1* bump for rc1
+		*2.2.16* #1961 changed to allow leading 0 extensions
+		*2.2.15.2* fixed bug install.php not converting destinations properly for new findmefollow format
 		*2.2.15.1* #2057 don't strip CID prefix if no prefix is being added
 		*2.2.15* #2024 provide alert when adding duplicate group number
+		*2.2.14.3* bumping to remove checksum error
+		*2.2.14.2* changed freePBX to FreePBX
+		*2.2.14.1* merge findmefollow/core extension destinations if any
 		*2.2.14* Fixed bug where nested CID prefixes ends up removing part of the valid CID info
-		*2.2.13* Add he_IL translation
+		*2.2.13* introduction of firstavailable firstnotonphone strategy that only rings one extension and optionally skips callwaiting REQUIRE CORE r3652
 		*2.2.12* never allow group to include itself as nnn# and create infinite loop
 		*2.2.11* changed _ALERT_INFO to __ALERT_INFO ('_' -> '__') so it is infinitely inheritted into the dialplan
 		*2.2.10* Added BLKVM DB tree to fix inability to transfer a received call to another user, and make NODEST stuff work overall
@@ -28,7 +35,6 @@
 	<menuitems>
 		<ringgroups>Ring Groups</ringgroups>
 	</menuitems>
-	<location>release/2.2/ringgroups-2.2.15.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-RingGroups</info>
-	<md5sum>aafb8edea59eb049a76f7bd6bc079b9d</md5sum>
+	<location>release/2.3/ringgroups-2.2.16.1.tgz</location>
+	<md5sum>2a295dd349cf30ab1cf3f1d93fff96f7</md5sum>
 </module>

Modified: freepbx-modules/trunk/modules/ringgroups/page.ringgroups.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/ringgroups/page.ringgroups.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/ringgroups/page.ringgroups.php (original)
+++ freepbx-modules/trunk/modules/ringgroups/page.ringgroups.php Mon Apr  7 13:18:05 2008
@@ -1,4 +1,4 @@
-<?php /* $Id: page.ringgroups.php 4233 2007-06-27 04:03:12Z p_lindheimer $ */
+<?php /* $Id: page.ringgroups.php 4911 2007-08-21 04:47:57Z p_lindheimer $ */
 //Copyright (C) 2004 Coalescent Systems Inc. (info at coalescentsystems.ca)
 //
 //This program is free software; you can redistribute it and/or
@@ -183,14 +183,16 @@
 					<b><?php echo _("ringall")?></b>:  <?php echo _("Ring all available channels until one answers (default)")?><br>
 					<b><?php echo _("hunt")?></b>: <?php echo _("Take turns ringing each available extension")?><br>
 					<b><?php echo _("memoryhunt")?></b>: <?php echo _("Ring first extension in the list, then ring the 1st and 2nd extension, then ring 1st 2nd and 3rd extension in the list.... etc.")?><br>
-                                        <b><?php echo _("*-prim")?></b>:  <?php echo _("These modes act as described above. However, if the primary extension (first in list) is occupied, the other extensions will not be rung. If the primary is freePBX DND, it won't be rung. If the primary is freePBX CF unconditional, then all will be rung")?><br>
+					<b><?php echo _("*-prim")?></b>:  <?php echo _("These modes act as described above. However, if the primary extension (first in list) is occupied, the other extensions will not be rung. If the primary is FreePBX DND, it won't be rung. If the primary is FreePBX CF unconditional, then all will be rung")?><br>
+					<b><?php echo _("firstavailable")?></b>:  <?php echo _("ring only the first available channel")?><br>
+					<b><?php echo _("firstnotonphone")?></b>:  <?php echo _("ring only the first channel which is not offhook - ignore CW")?><br>
 				</span>
 				</a></td>
 				<td>
 					<select name="strategy"/>
 					<?php
 						$default = (isset($strategy) ? $strategy : 'ringall');
-                                                $items = array('ringall','ringall-prim','hunt','hunt-prim','memoryhunt','memoryhunt-prim');
+                                                $items = array('ringall','ringall-prim','hunt','hunt-prim','memoryhunt','memoryhunt-prim','firstavailable','firstnotonphone');
 						foreach ($items as $item) {
 							echo '<option value="'.$item.'" '.($default == $item ? 'SELECTED' : '').'>'._($item);
 						}
@@ -254,7 +256,7 @@
 		<td>
 			<select name="ringing"/>
 			<?php
-				$tresults = music_list("/var/lib/asterisk/mohmp3");
+				$tresults = music_list($amp_conf['ASTVARLIBDIR']."/mohmp3");
 				$cur = (isset($ringing) ? $ringing : 'Ring');
 				echo '<option value="Ring">'._("Ring")."</option>";
 				if (isset($tresults[0])) {
@@ -337,7 +339,6 @@
 
 function checkGRP(theForm) {
 	var msgInvalidGrpNum = "<?php echo _('Invalid Group Number specified'); ?>";
-	var msgInvalidGrpNumStartWithZero = "<?php echo _('Group numbers with more than one digit cannot begin with 0'); ?>";
 	var msgInvalidExtList = "<?php echo _('Please enter an extension list.'); ?>";
 	var msgInvalidGrpPrefix = "<?php echo _('Invalid Caller ID prefix.'); ?>";
 	var msgInvalidTime = "<?php echo _('Invalid time specified'); ?>";
@@ -352,8 +353,6 @@
 	defaultEmptyOK = false;
 	if (!isInteger(theForm.account.value)) {
 		return warnInvalid(theForm.account, msgInvalidGrpNum);
-	} else if (theForm.account.value.indexOf('0') == 0 && theForm.account.value.length > 1) {
-		return warnInvalid(theForm.account, msgInvalidGrpNumStartWithZero);
 	}
 	
 	defaultEmptyOK = false;	

Modified: freepbx-modules/trunk/modules/speeddial/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/speeddial/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/speeddial/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/speeddial/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -1,12 +1,5 @@
 <?php
  /* $Id:$ */
-
-// returns a associative arrays with keys 'destination' and 'description'
-function speeddial_destinations() {
-	// return an associative array with destination and description
-	$extens[] = array('destination' => 'app-pbdirectory,pbdirectory,1', 'description' => 'Phonebook Directory');
-	return $extens;
-}
 
 function speeddial_get_config($engine) {
         $modulename = 'speeddial';
@@ -29,18 +22,6 @@
 				$ext->add('app-pbdirectory', $code, '', new ext_goto(1,'pbdirectory'));
 			}
 
-			// [macro-speeddial-clean]
-			// clean the 0's off of the variable named passed in ARG1
-			$ext->add('macro-speeddial-clean', 's', '', new ext_noop('Cleaing (stripping leading 0s from ${${ARG1}}) in var ${ARG1}'));
-			// while ( substr($$arg1,0,1) = '0') {
-			$ext->add('macro-speeddial-clean', 's', 'start', new ext_gotoif('$[${${ARG1}:0:1}=0]','strip','clean'));
-			//   $$arg1 = substr($$arg1,1);
-			$ext->add('macro-speeddial-clean', 's', 'strip', new ext_set('${ARG1}','${${ARG1}:1}'));
-			// }
-			$ext->add('macro-speeddial-clean', 's', '', new ext_goto('start'));
-			$ext->add('macro-speeddial-clean', 's', 'clean', new ext_noop('${ARG1} cleaned to ${${ARG1}}'));
-			
-			
 			// [macro-speeddial-lookup]
 			// arg1 is speed dial location,  arg2 (optional) is user caller ID
 			$ext->add('macro-speeddial-lookup', 's', '', new ext_gotoif('$["${ARG2}"=""]]','lookupsys'));
@@ -59,8 +40,7 @@
 			if (!empty($callcode)) {
 				$ext->add('app-speeddial', '_'.$callcode.'.', '', new ext_macro('user-callerid',''));
 				$ext->add('app-speeddial', '_'.$callcode.'.', '', new ext_set('SPEEDDIALLOCATION','${EXTEN:'.(strlen($callcode)).'}'));
-				$ext->add('app-speeddial', '_'.$callcode.'.', '', new ext_macro('speeddial-clean','SPEEDDIALLOCATION'));
-				$ext->add('app-speeddial', '_'.$callcode.'.', 'lookup', new ext_macro('speeddial-lookup','${SPEEDDIALLOCATION},${CALLERID(num)}'));
+				$ext->add('app-speeddial', '_'.$callcode.'.', 'lookup', new ext_macro('speeddial-lookup','${SPEEDDIALLOCATION},${AMPUSER}'));
 				$ext->add('app-speeddial', '_'.$callcode.'.', '', new ext_gotoif('$["${SPEEDDIALNUMBER}"=""]','failed'));
 				$ext->add('app-speeddial', '_'.$callcode.'.', '', new ext_dial('Local/${SPEEDDIALNUMBER}@from-internal/n','',''));
 				
@@ -78,18 +58,17 @@
 			$ext->add('app-speeddial-set', 's', '', new ext_macro('user-callerid',''));
 			// "enter speed dial location number"
 			$ext->add('app-speeddial-set', 's', 'setloc', new ext_read('newlocation','speed-enterlocation'));
-			$ext->add('app-speeddial-set', 's', '', new ext_macro('speeddial-clean','newlocation'));
-			$ext->add('app-speeddial-set', 's', 'lookup', new ext_macro('speeddial-lookup','${newlocation},${CALLERID(num)}'));
+			$ext->add('app-speeddial-set', 's', 'lookup', new ext_macro('speeddial-lookup','${newlocation},${AMPUSER}'));
 			$ext->add('app-speeddial-set', 's', 'lookup', new ext_gotoif('$["${SPEEDDIALNUMBER}"!=""]', 'conflicts'));
 			
 			// "enter phone number"
 			$ext->add('app-speeddial-set', 's', 'setnum', new ext_read('newnum','speed-enternumber'));
 			
 			
-			$ext->add('app-speeddial-set', 's', 'success', new ext_dbput('AMPUSER/${CALLERID(num)}/speeddials/${newlocation}','${newnum}'));
+			$ext->add('app-speeddial-set', 's', 'success', new ext_dbput('AMPUSER/${AMPUSER}/speeddials/${newlocation}','${newnum}'));
 			// "speed dial location "
 			$ext->add('app-speeddial-set', 's', '', new ext_playback('speed-dial'));
-			$ext->add('app-speeddial-set', 's', '', new ext_saynumber('${newlocation}'));
+			$ext->add('app-speeddial-set', 's', '', new ext_saydigits('${newlocation}'));
 			// "is set to "
 			$ext->add('app-speeddial-set', 's', '', new ext_playback('is-set-to'));
 			$ext->add('app-speeddial-set', 's', '', new ext_saydigits('${newnum}'));
@@ -99,15 +78,16 @@
 			// conflicts menu
 			// "speed dial location"
 			$ext->add('app-speeddial-set', 's', 'conflicts', new ext_playback('speed-dial'));
-			$ext->add('app-speeddial-set', 's', '', new ext_saynumber('${newlocation}'));
+			$ext->add('app-speeddial-set', 's', '', new ext_saydigits('${newlocation}'));
 			// "is already set."
 			$ext->add('app-speeddial-set', 's', '', new ext_playback('is-in-use'));
 			// "Press 1 to hear current phone number, 2 to pick a new location, 3 to set a new phone number"
 			$ext->add('app-speeddial-set', 's', '', new ext_background('press-1&to-listen-to-it&press-2&to-enter-a-diff&location&press-3&to-change&telephone-number'));
+			$ext->add('app-speeddial-set', 's', '', new ext_waitexten('60'));
 			
 			// "speed dial location"
 			$ext->add('app-speeddial-set', '1', '', new ext_playback('speed-dial'));
-			$ext->add('app-speeddial-set', '1', '', new ext_saynumber('${newlocation}'));
+			$ext->add('app-speeddial-set', '1', '', new ext_saydigits('${newlocation}'));
 			// "is set to "
 			$ext->add('app-speeddial-set', '1', '', new ext_playback('is-set-to'));
 			$ext->add('app-speeddial-set', '1', '', new ext_saydigits('${SPEEDDIALNUMBER}'));

Modified: freepbx-modules/trunk/modules/speeddial/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/speeddial/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/speeddial/module.xml (original)
+++ freepbx-modules/trunk/modules/speeddial/module.xml Mon Apr  7 13:18:05 2008
@@ -1,13 +1,20 @@
 <module>
 	<rawname>speeddial</rawname>
 	<name>Speed dial functions</name>
-	<version>1.0.2</version>
+	<version>1.0.4.2</version>
+	<changelog>
+		*1.0.4.2* #2329 add WaitExten after background
+		*1.0.4.1* bump for rc1
+		*1.0.4* #2049 remove use of speedial-clean, allow leading 0s
+		*1.0.3* changed ${CALLERID(number)} to ${AMPUSER} to accomodate CID number masquerading
+		*1.0.2* No comment
+		*1.0.1* First release for 2.2
+	</changelog>
 	<type>module</type>
-	<category>Basic</category>
+	<category>CID &amp; Number Management</category>
 	<depends>
 		<module>phonebook</module>
 	</depends>
-	<location>release/2.2/speeddial-1.0.2.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Features</info>
-	<md5sum>9a71b19ed9298b349ef3fb772738accc</md5sum>
+	<location>release/2.3/speeddial-1.0.4.1.tgz</location>
+	<md5sum>f9d72c28b47b47dd2a6facd96b308227</md5sum>
 </module>

Added: freepbx-modules/trunk/modules/timeconditions/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/timeconditions/install.php?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/timeconditions/install.php (added)
+++ freepbx-modules/trunk/modules/timeconditions/install.php Mon Apr  7 13:18:05 2008
@@ -1,0 +1,43 @@
+<?php
+
+global $db;
+global $amp_conf;
+
+$autoincrement = (($amp_conf["AMPDBENGINE"] == "sqlite") || ($amp_conf["AMPDBENGINE"] == "sqlite3")) ? "AUTOINCREMENT":"AUTO_INCREMENT";
+
+$sql = "CREATE TABLE IF NOT EXISTS timeconditions (
+	timeconditions_id INTEGER NOT NULL PRIMARY KEY $autoincrement,
+	displayname VARCHAR( 50 ) ,
+	time VARCHAR( 100 ) ,
+	truegoto VARCHAR( 50 ) ,
+	falsegoto VARCHAR( 50 ),
+	deptname VARCHAR( 50 )
+)";
+
+$check = $db->query($sql);
+if(DB::IsError($check)) {
+		die_freepbx("Can not create `timeconditions` table: " .  $check->getMessage() .  "\n");
+}
+
+$results = array();
+$sql = "SELECT timeconditions_id, truegoto, falsegoto FROM timeconditions";
+$results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
+if (!DB::IsError($results)) { // error - table must not be there
+	foreach ($results as $result) {
+		$old_false_dest    = $result['falsegoto'];
+		$old_true_dest     = $result['truegoto'];
+		$timeconditions_id = $result['timeconditions_id'];
+
+		$new_false_dest = merge_ext_followme(trim($old_false_dest));
+		$new_true_dest  = merge_ext_followme(trim($old_true_dest));
+		if (($new_true_dest != $old_true_dest) || ($new_false_dest != $old_false_dest)) {
+			$sql = "UPDATE timeconditions SET truegoto = '$new_true_dest', falsegoto = '$new_false_dest' WHERE timeconditions_id = $timeconditions_id  AND truegoto = '$old_true_dest' AND falsegoto ='$old_false_dest'";
+			$results = $db->query($sql);
+			if(DB::IsError($results)) {
+				die_freepbx($results->getMessage());
+			}
+		}
+	}
+}
+
+?>

Modified: freepbx-modules/trunk/modules/timeconditions/install.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/timeconditions/install.sql?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/timeconditions/install.sql (original)
+++ freepbx-modules/trunk/modules/timeconditions/install.sql Mon Apr  7 13:18:05 2008
@@ -1,1 +1,1 @@
-CREATE TABLE IF NOT EXISTS timeconditions ( timeconditions_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY , displayname VARCHAR( 50 ) , time VARCHAR( 100 ) , truegoto VARCHAR( 50 ) , falsegoto VARCHAR( 50 ), deptname VARCHAR( 50 )); 
+-- empty file, see http://freepbx.org/trac/ticket/1277

Modified: freepbx-modules/trunk/modules/timeconditions/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/timeconditions/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/timeconditions/module.xml (original)
+++ freepbx-modules/trunk/modules/timeconditions/module.xml Mon Apr  7 13:18:05 2008
@@ -1,13 +1,16 @@
 <module>
 	<rawname>timeconditions</rawname>
 	<name>Time Conditions</name>
-	<version>2.4.1</version>
+	<version>2.4.3.1</version>
 	<type>setup</type>
 	<category>Inbound Call Control</category>
 	<description>
 		Creates a condition where calls will to one of two destinations (eg, an extension, IVR, ring group..) based on the time and/or date. This can be used for example to ring a receptionist during the day, or go directly to an IVR at night.
 	</description>
 	<changelog>
+		*2.4.3.1* bump for rc1
+		*2.4.3* Added SQLite3 support, fixed ticket http://freepbx.org/trac/ticket/1774
+		*2.4.2* merge findmefollow/core extension destinations if any
 		*2.4.1* Add he_IL translation
 		*2.4* Upgrading module version to assist with trixbox upgrades, that have 2.3.1 already, so this needs to be higher. No other changes.	
 		*2.3* First release for FreePBX 2.2 - Fixed compatibility issue with new UI
@@ -15,7 +18,6 @@
 	<menuitems>
 		<timeconditions>Time Conditions</timeconditions>
 	</menuitems>
-	<location>release/2.2/timeconditions-2.4.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-TimeCond</info>
-	<md5sum>2154f8593c37358b4824f8d6831b7390</md5sum>
+	<location>release/2.3/timeconditions-2.4.3.tgz</location>
+	<md5sum>6f9c4e81c33290d3655ce2aa935b2aa5</md5sum>
 </module>

Added: freepbx-modules/trunk/modules/timeconditions/uninstall.sql
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/timeconditions/uninstall.sql?rev=5512&op=file
==============================================================================
--- freepbx-modules/trunk/modules/timeconditions/uninstall.sql (added)
+++ freepbx-modules/trunk/modules/timeconditions/uninstall.sql Mon Apr  7 13:18:05 2008
@@ -1,0 +1,1 @@
+DROP TABLE IF EXISTS `timeconditions`;

Modified: freepbx-modules/trunk/modules/voicemail/functions.inc.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/voicemail/functions.inc.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/voicemail/functions.inc.php (original)
+++ freepbx-modules/trunk/modules/voicemail/functions.inc.php Mon Apr  7 13:18:05 2008
@@ -38,15 +38,12 @@
 	$ext->add($id, $c, '', new ext_answer('')); // $cmd,1,Answer
 	$ext->add($id, $c, '', new ext_wait('1')); // $cmd,n,Wait(1)
 	$ext->add($id, $c, '', new ext_macro('user-callerid')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, '', new ext_macro('get-vmcontext','${CALLERID(num)}')); 
-	/* TODO: once depends functionality gets fixed in core this should be put back
-	$ext->add($id, $c, 'check', new ext_vmexists('${CALLERID(num)}@${VMCONTEXT}')); // n,VoiceMailMain(${VMCONTEXT})
-	*/
-	$ext->add($id, $c, 'check', new extension('MailBoxExists(${CALLERID(num)}@${VMCONTEXT})')); // n,VoiceMailMain(${VMCONTEXT})
+	$ext->add($id, $c, '', new ext_macro('get-vmcontext','${AMPUSER}')); 
+	$ext->add($id, $c, 'check', new ext_vmexists('${AMPUSER}@${VMCONTEXT}')); // n,VoiceMailMain(${VMCONTEXT})
 	$ext->add($id, $c, '', new ext_gotoif('$["${VMBOXEXISTSSTATUS}" = "SUCCESS"]', 'mbexist'));
 	$ext->add($id, $c, '', new ext_vmmain('')); // n,VoiceMailMain(${VMCONTEXT})
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
-	$ext->add($id, $c, 'mbexist', new ext_vmmain('${CALLERID(num)}@${VMCONTEXT}'),'check',101); // n,VoiceMailMain(${VMCONTEXT})
+	$ext->add($id, $c, 'mbexist', new ext_vmmain('${AMPUSER}@${VMCONTEXT}'),'check',101); // n,VoiceMailMain(${VMCONTEXT})
 	$ext->add($id, $c, '', new ext_macro('hangupcall')); // $cmd,n,Macro(user-callerid)
 }
 
@@ -81,7 +78,6 @@
 	$extdisplay = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:null;
 	$extension = isset($_REQUEST['extension'])?$_REQUEST['extension']:null;
 	$tech_hardware = isset($_REQUEST['tech_hardware'])?$_REQUEST['tech_hardware']:null;
-
 
        // We only want to hook 'users' or 'extensions' pages. 
 	if ($pagename != 'users' && $pagename != 'extensions')  
@@ -113,6 +109,10 @@
 	$currentcomponent->addoptlistitem('vmena', 'enabled', 'Enabled');
 	$currentcomponent->addoptlistitem('vmena', 'disabled', 'Disabled');
 	$currentcomponent->setoptlistopts('vmena', 'sort', false);
+	// Enable / Disable vmx list
+	$currentcomponent->addoptlistitem('vmxena', '', 'Disabled');
+	$currentcomponent->addoptlistitem('vmxena', 'checked', 'Enabled');
+	$currentcomponent->setoptlistopts('vmxena', 'sort', false);
 	// Yes / No Radio button list
 	$currentcomponent->addoptlistitem('vmyn', 'yes', 'yes');
 	$currentcomponent->addoptlistitem('vmyn', 'no', 'no');
@@ -131,12 +131,14 @@
 	$ext = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:null;
 	$extn = isset($_REQUEST['extension'])?$_REQUEST['extension']:null;
 	$display = isset($_REQUEST['display'])?$_REQUEST['display']:null;
-	
+
 	if ($ext==='') {
 		$extdisplay = $extn;
 	} else {
 		$extdisplay = $ext;
 	}
+
+
 	if ($action != 'del') {
 		$vmbox = voicemail_mailbox_get($extdisplay);
 		if ( $vmbox == null ) {
@@ -147,6 +149,8 @@
 			$email = null;
 			$pager = null;
 			$vmoptions = null;
+
+			$vmx_state = '';
 		} else {
 			$incontext = isset($vmbox['vmcontext'])?$vmbox['vmcontext']:'default';
 			$vmpwd = $vmbox['pwd'];
@@ -155,6 +159,8 @@
 			$pager = $vmbox['pager'];
 			$vmoptions = $vmbox['options'];
 			$vm = true;
+
+			$vmx_state = voicemail_vmxGet($extdisplay);
 		}
 
 		//loop through all options
@@ -179,9 +185,6 @@
 			$vmops_delete = 'no';
 		}
 
- 		//AMP Users can only add to their department's context
-		$vmcontext = isset($_SESSION["AMP_user"]->_deptname)?$_SESSION["AMP_user"]->_deptname:null;
-
 		if (empty($vmcontext)) 
 			$vmcontext = (isset($_REQUEST['vmcontext']) ? $_REQUEST['vmcontext'] : $incontext);
 		if (empty($vmcontext))
@@ -201,16 +204,17 @@
 		$msgInvalidVMContext = 'VM Context cannot be blank';
 
 		$section = 'Voicemail & Directory';
-		$currentcomponent->addguielem($section, new gui_selectbox('vm', $currentcomponent->getoptlist('vmena'), $vmselect, 'Status', '', false));
-		$currentcomponent->addguielem($section, new gui_textbox('vmpwd', $vmpwd, 'voicemail password', "This is the password used to access the voicemail system.<br><br>This password can only contain numbers.<br><br>A user can change the password you enter here after logging into the voicemail system ($fc_vm) with a phone.", "frm_${display}_isVoiceMailEnabled() && !isInteger()", $msgInvalidVmPwd, false));
-		$currentcomponent->addguielem($section, new gui_textbox('email', $email, 'email address', "The email address that voicemails are sent to.", "frm_${display}_isVoiceMailEnabled() && !isEmail()", $msgInvalidEmail, true));
-		$currentcomponent->addguielem($section, new gui_textbox('pager', $pager, 'pager email address', "Pager/mobile email address that short voicemail notifcations are sent to.", "frm_${display}_isVoiceMailEnabled() && !isEmail()", $msgInvalidEmail, true));
-		$currentcomponent->addguielem($section, new gui_radio('attach', $currentcomponent->getoptlist('vmyn'), $vmops_attach, 'email attachment', "Option to attach voicemails to email."));
-		$currentcomponent->addguielem($section, new gui_radio('saycid', $currentcomponent->getoptlist('vmyn'), $vmops_saycid, 'Play CID', "Read back caller's telephone number prior to playing the incoming message, and just after announcing the date and time the message was left."));
-		$currentcomponent->addguielem($section, new gui_radio('envelope', $currentcomponent->getoptlist('vmyn'), $vmops_envelope, 'Play Envelope', "Envelope controls whether or not the voicemail system will play the message envelope (date/time) before playing the voicemail message. This settng does not affect the operation of the envelope option in the advanced voicemail menu."));
-		$currentcomponent->addguielem($section, new gui_radio('delete', $currentcomponent->getoptlist('vmyn'), $vmops_delete, 'Delete Vmail', "If set to \"yes\" the message will be deleted from the voicemailbox (after having been emailed). Provides functionality that allows a user to receive their voicemail via email alone, rather than having the voicemail able to be retrieved from the Webinterface or the Extension handset.  CAUTION: MUST HAVE attach voicemail to email SET TO YES OTHERWISE YOUR MESSAGES WILL BE LOST FOREVER."));
-		$currentcomponent->addguielem($section, new gui_textbox('options', $options, 'vm options', 'Separate options with pipe ( | )<br><br>ie: review=yes|maxmessage=60'));
-		$currentcomponent->addguielem($section, new gui_textbox('vmcontext', $vmcontext, 'vm context', '', "frm_${display}_isVoiceMailEnabled() && isEmpty()", $msgInvalidVMContext, false));
+		$currentcomponent->addguielem($section, new gui_selectbox('vm', $currentcomponent->getoptlist('vmena'), $vmselect, _('Status'), '', false));
+		$currentcomponent->addguielem($section, new gui_textbox('vmpwd', $vmpwd, _('Voicemail Password'), sprintf(_("This is the password used to access the voicemail system.%sThis password can only contain numbers.%sA user can change the password you enter here after logging into the voicemail system (%s) with a phone."),"<br /><br />","<br /><br />",$fc_vm), "frm_${display}_isVoiceMailEnabled() && !isInteger()", $msgInvalidVmPwd, false));
+		$currentcomponent->addguielem($section, new gui_textbox('email', $email, _('Email Address'), _("The email address that voicemails are sent to."), "frm_${display}_isVoiceMailEnabled() && !isEmail()", $msgInvalidEmail, true));
+		$currentcomponent->addguielem($section, new gui_textbox('pager', $pager, _('Pager Email Address'), _("Pager/mobile email address that short voicemail notifcations are sent to."), "frm_${display}_isVoiceMailEnabled() && !isEmail()", $msgInvalidEmail, true));
+		$currentcomponent->addguielem($section, new gui_radio('attach', $currentcomponent->getoptlist('vmyn'), $vmops_attach, _('Email Attachment'), _("Option to attach voicemails to email.")));
+		$currentcomponent->addguielem($section, new gui_radio('saycid', $currentcomponent->getoptlist('vmyn'), $vmops_saycid, _('Play CID'), _("Read back caller's telephone number prior to playing the incoming message, and just after announcing the date and time the message was left.")));
+		$currentcomponent->addguielem($section, new gui_radio('envelope', $currentcomponent->getoptlist('vmyn'), $vmops_envelope, _('Play Envelope'), _("Envelope controls whether or not the voicemail system will play the message envelope (date/time) before playing the voicemail message. This settng does not affect the operation of the envelope option in the advanced voicemail menu.")));
+		$currentcomponent->addguielem($section, new gui_radio('delete', $currentcomponent->getoptlist('vmyn'), $vmops_delete, _('Delete Vmail'), _("If set to \"yes\" the message will be deleted from the voicemailbox (after having been emailed). Provides functionality that allows a user to receive their voicemail via email alone, rather than having the voicemail able to be retrieved from the Webinterface or the Extension handset.  CAUTION: MUST HAVE attach voicemail to email SET TO YES OTHERWISE YOUR MESSAGES WILL BE LOST FOREVER.")));
+		$currentcomponent->addguielem($section, new gui_textbox('options', $options, _('VM Options'), sprintf(_('Separate options with pipe ( | )%sie: review=yes|maxmessage=60'),"<br /><br />")));
+		$currentcomponent->addguielem($section, new gui_textbox('vmcontext', $vmcontext, _('VM Context'), _('This is the Voicemail Context which is normally set to default. Do not change unless you understand the implications.'), "frm_${display}_isVoiceMailEnabled() && isEmpty()", $msgInvalidVMContext, false));
+		$currentcomponent->addguielem($section, new gui_selectbox('vmx_state', $currentcomponent->getoptlist('vmxena'), $vmx_state, 'VmX Locater&trade;', _('Enable/Disable the VmX Locater feature for this user. When enabled all settings are controlled by the user in the User Portal (ARI). Disabling will not delete any existing user settings but will disable access to the feature'), false));
 	}
 }
 
@@ -227,6 +231,9 @@
 			needreload();
 		break;
 		case "del":
+			// call remove before del, it needs to know context info
+			//
+			voicemail_mailbox_remove($extdisplay);
 			voicemail_mailbox_del($extdisplay);
 			needreload();
 		break;
@@ -258,6 +265,35 @@
 	return null;
 }
 
+function voicemail_mailbox_remove($mbox) {
+	global $amp_conf;
+	$uservm = voicemail_getVoicemail();
+	$vmcontexts = array_keys($uservm);
+
+	$return = true;
+
+	foreach ($vmcontexts as $vmcontext) {
+		if(isset($uservm[$vmcontext][$mbox])){
+
+			$vm_dir = $amp_conf['ASTSPOOLDIR']."/voicemail/$vmcontext/$mbox";
+			exec("rm -rf $vm_dir",$output,$ret);
+			if ($ret) {
+				$return = false;
+				$text   = sprintf(_("Failed to delete vmbox: %s@%s"),$mbox, $vmcontext);
+				$etext  = sprintf(_("failed with retcode %s while removing %s:"),$ret, $vm_dir)."<br>";
+				$etext .= implode("<br>",$output);
+				$nt =& notifications::create($db);
+				$nt->add_error('voicemail', 'MBOXREMOVE', $text, $etext, '', true, true);
+				//
+				// TODO: this does not work but we should give some sort of feedback that id did not work
+				//
+				// echo "<script>javascript:alert('$text\n"._("See notification panel for details")."')</script>";
+			}
+		}
+	}
+	return $return;	
+}
+
 function voicemail_mailbox_del($mbox) {
 	$uservm = voicemail_getVoicemail();
 	$vmcontexts = array_keys($uservm);
@@ -277,7 +313,7 @@
 	//check if VM box already exists
 	if ( voicemail_mailbox_get($mbox) != null ) {
 		trigger_error("Voicemail mailbox '$mbox' already exists, call to voicemail_maibox_add failed");
-		die();
+		die_freepbx();
 	}
 	
 	$uservm = voicemail_getVoicemail();
@@ -322,7 +358,7 @@
 	global $amp_conf;
 
 	// just in case someone tries to be sneaky and not call getVoicemail() first..
-	if ($vmconf == null) die('Error: Trying to write null voicemail file! I refuse to contiune!');
+	if ($vmconf == null) die_freepbx('Error: Trying to write null voicemail file! I refuse to contiune!');
 	
 	// yes, this is hardcoded.. is this a bad thing?
 	write_voicemailconf(rtrim($amp_conf["ASTETCDIR"],"/")."/voicemail.conf", $vmconf, $section);
@@ -340,4 +376,19 @@
 	return $vmconf;
 }
 
+function voicemail_vmxGet($extension) {
+	global $astman;                                                                                                                                                                                                    
+		                                                                                                                                                                                                                     
+	// Retrieve the state
+	$vmx_state=$astman->database_get("AMPUSER",$extension."/vmx/unavail/state");
+	if (isset($vmx_state) && (trim($vmx_state) == 'enabled' || trim($vmx_state) == 'disabled')) {
+		$vmx_state='checked';
+	} else {
+		$vmx_state='';
+	}
+
+	return $vmx_state;
+}                                                                                                                                                                                                                    
+
+
 ?>

Modified: freepbx-modules/trunk/modules/voicemail/install.php
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/voicemail/install.php?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/voicemail/install.php (original)
+++ freepbx-modules/trunk/modules/voicemail/install.php Mon Apr  7 13:18:05 2008
@@ -16,12 +16,11 @@
 $fcc->update();
 unset($fcc);
 
-//1.6.1
+//1.6.2
 $modinfo = module_getinfo('voicemail');
 if (is_array($modinfo)) {
 	$ver = $modinfo['voicemail']['dbversion'];
-	if (version_compare($ver,'1.6.1','lt')) { //we have to fix existing users with wrong values for vm ticket #1697
-		checkAstMan();
+	if (version_compare($ver,'1.6.2','lt')) { //we have to fix existing users with wrong values for vm ticket #1697
 		if ($astman) {
 			$sql = "select * from users where voicemail='disabled' or voicemail='';";
 			$users = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
@@ -30,9 +29,10 @@
 			}
 		} else {
 			echo _("Cannot connect to Asterisk Manager with ").$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"];
+			return false;
 		}
 		sql("update users set voicemail='novm' where voicemail='disabled' or voicemail='';");
 	}
 }
 
-?>
+?>

Modified: freepbx-modules/trunk/modules/voicemail/module.xml
URL: http://svn.debian.org/wsvn/pkg-voip/freepbx-modules/trunk/modules/voicemail/module.xml?rev=5512&op=diff
==============================================================================
--- freepbx-modules/trunk/modules/voicemail/module.xml (original)
+++ freepbx-modules/trunk/modules/voicemail/module.xml Mon Apr  7 13:18:05 2008
@@ -1,14 +1,26 @@
 <module>
 	<rawname>voicemail</rawname>
 	<name>Voicemail</name>
-	<version>1.6.4.2</version>
+	<version>2.0.3.4</version>
+	<candisable>no</candisable>
+	<canuninstall>no</canuninstall>
 	<changelog>
-		*1.6.4.2* #2232 checking for voicemail failure on Asterisk 1.4 and possible 1.2 with some configs
-		*1.6.4.1* MailBoxExists needs 'j' option for Asterisk 1.4 (and technically this is correct syntax)
-		*1.6.4* add class to define MailBoxExists and removed the dependency on 2.2.2 - since 2.2.2 dependency checking is broken
-		*1.6.3* #1976 - check if mailbox exists and enter with no arguments if not
-		*1.6.2* Remove hardcoded paths to voicemail.conf
-		*1.6.1* Bump version to fix existing extensions with disabled voicemail #1697
+		*2.0.3.4* Fix some labeling and make localization friendly
+		*2.0.3.3* #2232 call to VoiceMailMain() need ${AMPUSER} was fixed wrong
+		*2.0.3.2* bump for rc1
+		*2.0.3.1* #2232 checking for voicemial failure on Asterisk 1.4
+		*2.0.3* #1836 - remove mailbox form filesystem after deleting an extension
+		*2.0.2.4* changed install script to return false on astman not there
+		*2.0.2.3* remove setting vmcontext to department, fixed #2153 and #2136
+		*2.0.2.2* MailBoxExists needs 'j' option for Asterisk 1.4 (and technically this is correct syntax)
+	  *2.0.2.1* added candisable = no for module admin
+	  *2.0.2* changed ${CALLERID(number)} to ${AMPUSER} to accomodate CID number masquerading
+		*2.0.1.1* removed depends on 2.2.2 - classes are in all version of 2.3
+		*2.0.1* #1976 - check if mailbox exists and enter with no arguments if not
+		*2.0.0* Bumped version number to avoid confusion with freepbx 2.2.x versions
+		*1.6.3* Remove hardcoded paths to voicemail.conf
+		*1.6.2* Bump version to fix existing extensions with disabled voicemail #1697
+		*1.6.1* Added support to enable/disable VmX Locator (personal ivr)
 		*1.6* Re-Fix 1.5.2, bump version for 2.2rc2 release.
 		*1.5.3* Fix for vm Javascript sanity checks only working in DevAndUser mode.
 		*1.5.2* Fix vm not appearing in DeviceAndUser mode
@@ -21,7 +33,6 @@
 	<description>This module allows you to configure Voicemail for a user or extension</description>
 	<type>setup</type>
 	<category>Basic</category>
-	<location>release/2.2/voicemail-1.6.4.1.tgz</location>
-	<info>http://aussievoip.com.au/wiki/freePBX-Features</info>
-	<md5sum>6232b5aad95c520754d1a47f604b4847</md5sum>
+	<location>release/2.3/voicemail-2.0.3.3.tgz</location>
+	<md5sum>6a2ec22f303465579eb20d40e22a71f2</md5sum>
 </module>




More information about the Pkg-voip-commits mailing list