[Pkg-voip-commits] r1767 - in asterisk/branches/sarge/debian: .
patches
Tzafrir Cohen
tzafrir-guest at costa.debian.org
Tue May 16 10:42:28 UTC 2006
Author: tzafrir-guest
Date: 2006-05-16 10:42:26 +0000 (Tue, 16 May 2006)
New Revision: 1767
Added:
asterisk/branches/sarge/debian/asterisk.init
asterisk/branches/sarge/debian/patches/brazilian_syntax.dpatch
asterisk/branches/sarge/debian/patches/func_odbc_12.dpatch
asterisk/branches/sarge/debian/patches/sys_editline.dpatch
asterisk/branches/sarge/debian/patches/sys_readline.dpatch
Modified:
asterisk/branches/sarge/debian/asterisk-bristuff.install
asterisk/branches/sarge/debian/asterisk-classic.install
asterisk/branches/sarge/debian/changelog
asterisk/branches/sarge/debian/patches/00list
asterisk/branches/sarge/debian/patches/30_ast-data-dir.dpatch
asterisk/branches/sarge/debian/patches/option_detach.dpatch
Log:
* sys_readline.dpatch: Realine support in the CLI. TODO: tab completion
* sys_editline.dpatch: alternativly, simply use the system version of
editline (not used).
* Copied configuration from rapid_config instead of ast_config
* func_odbc_12.dpatch: backport of func_odbc (Closes: #364633)
* brazilian_syntax.dpatch
* The data_dir patch also moves agi-bin/ and firmware/
* option_detach: using -F instead of -D (the same as upstream)
Modified: asterisk/branches/sarge/debian/asterisk-bristuff.install
===================================================================
--- asterisk/branches/sarge/debian/asterisk-bristuff.install 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/asterisk-bristuff.install 2006-05-16 10:42:26 UTC (rev 1767)
@@ -1,4 +1,3 @@
-bristuff/etc/default etc/
bristuff/usr/lib/asterisk usr/lib/
bristuff/usr/sbin usr/
bristuff/usr/share/man usr/share/
Modified: asterisk/branches/sarge/debian/asterisk-classic.install
===================================================================
--- asterisk/branches/sarge/debian/asterisk-classic.install 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/asterisk-classic.install 2006-05-16 10:42:26 UTC (rev 1767)
@@ -1,4 +1,3 @@
-etc/default
usr/lib/asterisk
usr/sbin
var/lib/asterisk
Added: asterisk/branches/sarge/debian/asterisk.init
===================================================================
--- asterisk/branches/sarge/debian/asterisk.init 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/asterisk.init 2006-05-16 10:42:26 UTC (rev 1767)
@@ -0,0 +1,185 @@
+#! /bin/sh
+#
+# asterisk start the asterisk PBX
+# (c) Mark Purcell <msp at debian.org>
+# May be distributed under the terms of this General Public License
+#
+# Based on:
+#
+# skeleton example file to build /etc/init.d/ scripts.
+# This file should be used to construct scripts for /etc/init.d.
+#
+# Written by Miquel van Smoorenburg <miquels at cistron.nl>.
+# Modified for Debian GNU/Linux
+# by Ian Murdock <imurdock at gnu.ai.mit.edu>.
+#
+# Version: @(#)skeleton 1.9 26-Feb-2001 miquels at cistron.nl
+#
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+NAME=asterisk
+USER=$NAME
+GROUP=$USER
+DAEMON=/usr/sbin/$NAME
+DESC="Asterisk PBX"
+PIDFILE="/var/run/asterisk/asterisk.pid"
+ASTSAFE_PIDFILE="/var/run/asterisk/asterisk_safe.pid"
+UMASK=007 # by default
+
+# by default: use real-time priority
+PARAMS=""
+AST_REALTIME="yes"
+RUNASTERISK="yes"
+if [ -r /etc/default/$NAME ]; then . /etc/default/$NAME; fi
+
+if [ "$RUNASTERISK" != "yes" ];then
+ echo "Asterisk not yet configured. Edit /etc/default/asterisk first."
+ exit 0
+fi
+
+if [ "$AST_REALTIME" != "no" ]
+then
+ PARAMS="$PARAMS -p"
+fi
+
+if [ "x$USER" = "x" ]
+then
+ echo "Error: empty USER name"
+ exit 1
+fi
+if [ "`id -u "$USER"`" = 0 ]
+then
+ echo "Starting as root not supported."
+ exit 1
+fi
+PARAMS="$PARAMS -U $USER"
+
+if [ "x$AST_DEBUG_PARAMS" = x ]
+then
+ AST_DEBUG_PARAMS=-cvvvvvddddd
+fi
+if [ "$RUNASTSAFE" = "yes" ];then
+ # The value of WRAPPER_DAEMON in can be set in /etc/default/asterisk
+ WRAPPER_DAEMON=${WRAPPER_DAEMON:-/usr/sbin/safe_asterisk}
+ REALDAEMON="$WRAPPER_DAEMON"
+else
+ REALDAEMON="$DAEMON"
+fi
+
+test -x $DAEMON || exit 0
+
+if [ "$UMASK" != '' ]
+then
+ umask $UMASK
+fi
+
+set -e
+
+status() {
+ plist=`ps auxw | grep "$DAEMON" | grep -v grep | awk '{print $2}' | tr '\012' ' '`
+ if [ "$plist" = "" ]; then
+ echo "$DESC is stopped"
+ return 1
+ else
+ echo "$DESC is running: $plist"
+ return 0
+ fi
+}
+
+case "$1" in
+ debug)
+ # we add too many special parameters that I don't want to skip
+ # accidentally. I'm afraid that skipping -U once may cause
+ # confusing results. I also want to maintain the user's choice
+ # of -p
+ echo "Debugging $DESC: "
+ $DAEMON $PARAMS $AST_DEBUG_PARAMS
+ exit 0
+ ;;
+ start)
+ if status > /dev/null; then
+ echo "$DESC is already running. Use restart."
+ exit 1
+ fi
+ echo -n "Starting $DESC: "
+ if [ "$RUNASTSAFE" != "yes" ];then
+ # TODO: what if we cought the wrapper just as its asterisk
+ # was killed? status should check for the wrapper if we're in
+ # "safe mode"
+ if status > /dev/null; then
+ echo "$DESC is already running. Use restart."
+ exit 1
+ fi
+ start-stop-daemon --start --group $GROUP --pidfile "$PIDFILE" \
+ --exec $REALDAEMON -- $PARAMS
+ else
+ start-stop-daemon --start --group $GROUP --make-pidfile \
+ --pidfile "$ASTSAFE_PIDFILE" \
+ --exec $REALDAEMON -- $PARAMS
+ fi
+
+
+ echo "$NAME."
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ if [ "$RUNASTSAFE" = "yes" ];then
+ # hopefully this will work. Untested
+ $REALDAEMON -rx 'stop now' > /dev/null || true
+ else
+ # Try gracefully.
+ # this may hang in some cases. Specifically, when the asterisk
+ # processes is stopped. No bother to worry about cleanup:
+ # it will either fail or die when asterisk dies.
+ ( $DAEMON -rx 'stop now' > /dev/null 2>&1 & ) &
+ fi
+ echo -n "$NAME"
+ ## giving a small grace time to shut down cleanly.
+ #sleep 2 # you can add timeouts in the comma
+ if [ "$RUNASTSAFE" = "yes" ];then
+ start-stop-daemon --quiet --pidfile $ASTSAFE_PIDFILE --oknodo \
+ --stop
+ fi
+ # just making sure it's really, really dead.
+ # KILL is necessary just in case there's an asterisk -r in the background
+ start-stop-daemon --stop --quiet --oknodo --retry=0/2/TERM/2/KILL/5 --exec $DAEMON
+ echo "."
+ ;;
+ reload)
+ echo "Reloading $DESC configuration files."
+ $DAEMON -rx 'reload'
+ ;;
+ logger-reload)
+ $DAEMON -rx 'logger reload'
+ ;;
+ extensions-reload)
+ echo "Reloading $DESC configuration files."
+ $DAEMON -rx 'extensions reload'
+ ;;
+ restart|force-reload)
+ $0 stop
+ $0 start
+ ;;
+ status)
+ status
+ exit $?
+ ;;
+ zaptel-fix)
+ echo "Unloading and reloading loading Asterisk and Zaptel:"
+ $0 stop
+ /etc/init.d/zaptel unload
+ # load modules from /etc/modules. This will break if you count on
+ # discover/hotplug
+ /etc/init.d/module-init-tools
+ /etc/init.d/zaptel start
+ $0 start
+ ;;
+ *)
+ N=/etc/init.d/$NAME
+ # echo "Usage: $N {start|stop|restart|reload|logger-reload|extensions-reload|force-reload}" >&2
+ echo "Usage: $N {start|stop|status|debug|restart|force-reload|zaptel-fix}" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
Modified: asterisk/branches/sarge/debian/changelog
===================================================================
--- asterisk/branches/sarge/debian/changelog 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/changelog 2006-05-16 10:42:26 UTC (rev 1767)
@@ -16,8 +16,16 @@
* reunite init.d and logrotate scripts in the package asterisk
* Re-add correct_pid_display.dpatch
* bristuff 0.3.0-PRE1p (gsm functionality missing: needs libgstam)
+ * sys_readline.dpatch: Realine support in the CLI. TODO: tab completion
+ * sys_editline.dpatch: alternativly, simply use the system version of
+ editline (not used).
+ * Copied configuration from rapid_config instead of ast_config
+ * func_odbc_12.dpatch: backport of func_odbc (Closes: #364633)
+ * brazilian_syntax.dpatch
+ * The data_dir patch also moves agi-bin/ and firmware/
+ * option_detach: using -F instead of -D (the same as upstream)
- -- Tzafrir Cohen <tzafrir.cohen at xorcom.com> Thu, 11 May 2006 18:14:36 +0300
+ -- Tzafrir Cohen <tzafrir.cohen at xorcom.com> Tue, 16 May 2006 13:40:21 +0300
asterisk (1:1.2.7.1.dfsg-2) unstable; urgency=high
Modified: asterisk/branches/sarge/debian/patches/00list
===================================================================
--- asterisk/branches/sarge/debian/patches/00list 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/patches/00list 2006-05-16 10:42:26 UTC (rev 1767)
@@ -6,6 +6,9 @@
50_debian-libgsm.dpatch
95_conf_sample.dpatch
98_fpm-sounds.dpatch
+sys_readline
+func_odbc_12
+brazilian_syntax
pubkey_jnctn
nomarch
nooptimize
Modified: asterisk/branches/sarge/debian/patches/30_ast-data-dir.dpatch
===================================================================
--- asterisk/branches/sarge/debian/patches/30_ast-data-dir.dpatch 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/patches/30_ast-data-dir.dpatch 2006-05-16 10:42:26 UTC (rev 1767)
@@ -8,10 +8,10 @@
## -- is applied upstream for 1.2
@DPATCH@
-diff -urNad asterisk-1.2.1.dfsg~/asterisk.c asterisk-1.2.1.dfsg/asterisk.c
---- asterisk-1.2.1.dfsg~/asterisk.c 2005-11-29 18:24:39.000000000 +0000
-+++ asterisk-1.2.1.dfsg/asterisk.c 2005-12-07 21:52:07.000000000 +0000
-@@ -202,6 +202,7 @@
+diff -urNad asterisk-1.2.7.1.dfsg/asterisk.c /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/asterisk.c
+--- asterisk-1.2.7.1.dfsg/asterisk.c 2006-05-13 18:14:15.970288503 +0300
++++ /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/asterisk.c 2006-05-13 18:14:16.228355957 +0300
+@@ -216,6 +216,7 @@
char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH];
char ast_config_AST_MONITOR_DIR[AST_CONFIG_MAX_PATH];
char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH];
@@ -19,26 +19,26 @@
char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH];
char ast_config_AST_AGI_DIR[AST_CONFIG_MAX_PATH];
char ast_config_AST_DB[AST_CONFIG_MAX_PATH];
-@@ -1788,6 +1789,7 @@
- ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_VAR_DIR));
+@@ -1882,6 +1883,7 @@
+ ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_MODULE_DIR));
snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR);
ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR));
+ ast_copy_string(ast_config_AST_DATA_DIR, AST_DATA_DIR, sizeof(ast_config_AST_DATA_DIR));
ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR));
ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR));
ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB));
-@@ -1823,6 +1826,8 @@
+@@ -1918,6 +1920,8 @@
ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR));
snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/astdb", v->value);
- snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value);
+ snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value);
+ } else if (!strcasecmp(v->name, "astdatadir")) {
+ ast_copy_string(ast_config_AST_DATA_DIR, v->value, sizeof(ast_config_AST_DATA_DIR));
} else if (!strcasecmp(v->name, "astlogdir")) {
ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR));
} else if (!strcasecmp(v->name, "astagidir")) {
-diff -urNad asterisk-1.2.1.dfsg~/build_tools/make_defaults_h asterisk-1.2.1.dfsg/build_tools/make_defaults_h
---- asterisk-1.2.1.dfsg~/build_tools/make_defaults_h 2005-06-20 18:26:08.000000000 +0100
-+++ asterisk-1.2.1.dfsg/build_tools/make_defaults_h 2005-12-07 21:52:07.000000000 +0000
+diff -urNad asterisk-1.2.7.1.dfsg/build_tools/make_defaults_h /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/build_tools/make_defaults_h
+--- asterisk-1.2.7.1.dfsg/build_tools/make_defaults_h 2005-06-20 20:26:08.000000000 +0300
++++ /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/build_tools/make_defaults_h 2006-05-13 18:14:16.228355957 +0300
@@ -11,6 +11,7 @@
#define AST_MODULE_DIR "${INSTALL_PATH}${MODULES_DIR}"
#define AST_SPOOL_DIR "${INSTALL_PATH}${ASTSPOOLDIR}"
@@ -57,9 +57,21 @@
+#define AST_IMAGES "${INSTALL_PATH}${ASTDATADIR}/images"
END
-diff -urNad asterisk-1.2.1.dfsg~/configs/musiconhold.conf.sample asterisk-1.2.1.dfsg/configs/musiconhold.conf.sample
---- asterisk-1.2.1.dfsg~/configs/musiconhold.conf.sample 2005-11-29 18:24:39.000000000 +0000
-+++ asterisk-1.2.1.dfsg/configs/musiconhold.conf.sample 2005-12-07 21:52:07.000000000 +0000
+diff -urNad asterisk-1.2.7.1.dfsg/channels/chan_iax2.c /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/channels/chan_iax2.c
+--- asterisk-1.2.7.1.dfsg/channels/chan_iax2.c 2006-03-31 22:11:26.000000000 +0300
++++ /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/channels/chan_iax2.c 2006-05-13 18:27:17.074963284 +0300
+@@ -1367,7 +1367,7 @@
+ cur = cur->next;
+ }
+ /* Now that we've freed them, load the new ones */
+- snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_VAR_DIR);
++ snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
+ fwd = opendir(dir);
+ if (fwd) {
+ while((de = readdir(fwd))) {
+diff -urNad asterisk-1.2.7.1.dfsg/configs/musiconhold.conf.sample /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/configs/musiconhold.conf.sample
+--- asterisk-1.2.7.1.dfsg/configs/musiconhold.conf.sample 2005-11-29 20:24:39.000000000 +0200
++++ /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/configs/musiconhold.conf.sample 2006-05-13 18:14:16.228355957 +0300
@@ -4,7 +4,7 @@
[default]
@@ -69,10 +81,10 @@
; valid mode options:
; quietmp3 -- default
-diff -urNad asterisk-1.2.1.dfsg~/file.c asterisk-1.2.1.dfsg/file.c
---- asterisk-1.2.1.dfsg~/file.c 2005-11-29 18:24:39.000000000 +0000
-+++ asterisk-1.2.1.dfsg/file.c 2005-12-07 21:52:07.000000000 +0000
-@@ -312,7 +312,7 @@
+diff -urNad asterisk-1.2.7.1.dfsg/file.c /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/file.c
+--- asterisk-1.2.7.1.dfsg/file.c 2006-01-10 00:07:26.000000000 +0200
++++ /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/file.c 2006-05-13 18:14:16.228355957 +0300
+@@ -313,7 +313,7 @@
} else {
char tmp[AST_CONFIG_MAX_PATH] = "";
@@ -81,9 +93,9 @@
fnsize = strlen(tmp) + strlen(filename) + strlen(type) + 3;
fn = malloc(fnsize);
if (fn)
-diff -urNad asterisk-1.2.1.dfsg~/image.c asterisk-1.2.1.dfsg/image.c
---- asterisk-1.2.1.dfsg~/image.c 2005-11-29 18:24:39.000000000 +0000
-+++ asterisk-1.2.1.dfsg/image.c 2005-12-07 21:52:07.000000000 +0000
+diff -urNad asterisk-1.2.7.1.dfsg/image.c /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/image.c
+--- asterisk-1.2.7.1.dfsg/image.c 2006-03-24 16:48:11.000000000 +0200
++++ /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/image.c 2006-05-13 18:14:16.228355957 +0300
@@ -108,9 +108,9 @@
snprintf(buf, len, "%s.%s", filename, ext);
} else {
@@ -96,9 +108,9 @@
}
}
-diff -urNad asterisk-1.2.1.dfsg~/include/asterisk.h asterisk-1.2.1.dfsg/include/asterisk.h
---- asterisk-1.2.1.dfsg~/include/asterisk.h 2005-11-30 03:37:37.000000000 +0000
-+++ asterisk-1.2.1.dfsg/include/asterisk.h 2005-12-07 21:52:07.000000000 +0000
+diff -urNad asterisk-1.2.7.1.dfsg/include/asterisk.h /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/include/asterisk.h
+--- asterisk-1.2.7.1.dfsg/include/asterisk.h 2005-11-30 05:37:37.000000000 +0200
++++ /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/include/asterisk.h 2006-05-13 18:14:16.228355957 +0300
@@ -29,6 +29,7 @@
extern char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_MONITOR_DIR[AST_CONFIG_MAX_PATH];
@@ -107,10 +119,10 @@
extern char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_AGI_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_DB[AST_CONFIG_MAX_PATH];
-diff -urNad asterisk-1.2.1.dfsg~/Makefile asterisk-1.2.1.dfsg/Makefile
---- asterisk-1.2.1.dfsg~/Makefile 2005-12-05 06:47:51.000000000 +0000
-+++ asterisk-1.2.1.dfsg/Makefile 2005-12-07 21:57:47.000000000 +0000
-@@ -108,6 +108,7 @@
+diff -urNad asterisk-1.2.7.1.dfsg/Makefile /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/Makefile
+--- asterisk-1.2.7.1.dfsg/Makefile 2006-04-12 00:58:47.000000000 +0300
++++ /tmp/dpep.um4nZ3/asterisk-1.2.7.1.dfsg/Makefile 2006-05-13 18:26:34.253802810 +0300
+@@ -110,6 +110,7 @@
ifneq ($(OSARCH),SunOS)
ASTLIBDIR=$(INSTALL_PREFIX)/usr/lib/asterisk
ASTVARLIBDIR=$(INSTALL_PREFIX)/var/lib/asterisk
@@ -118,7 +130,7 @@
ASTETCDIR=$(INSTALL_PREFIX)/etc/asterisk
ASTSPOOLDIR=$(INSTALL_PREFIX)/var/spool/asterisk
ASTLOGDIR=$(INSTALL_PREFIX)/var/log/asterisk
-@@ -115,7 +116,7 @@
+@@ -117,10 +118,10 @@
ASTCONFPATH=$(ASTETCDIR)/asterisk.conf
ASTBINDIR=$(INSTALL_PREFIX)/usr/bin
ASTSBINDIR=$(INSTALL_PREFIX)/usr/sbin
@@ -126,9 +138,21 @@
+ ASTVARRUNDIR=$(INSTALL_PREFIX)/var/run/asterisk
ASTMANDIR=$(INSTALL_PREFIX)/usr/share/man
MODULES_DIR=$(ASTLIBDIR)/modules
+- AGI_DIR=$(ASTVARLIBDIR)/agi-bin
++ AGI_DIR=$(ASTDATADIR)/agi-bin
+ else
+ ASTLIBDIR=$(INSTALL_PREFIX)/opt/asterisk/lib
+ ASTVARLIBDIR=$(INSTALL_PREFIX)/var/opt/asterisk/lib
+@@ -136,6 +137,7 @@
+ MODULES_DIR=$(ASTLIBDIR)/modules
AGI_DIR=$(ASTVARLIBDIR)/agi-bin
-@@ -539,38 +540,38 @@
+ endif
++FIRMWARE_DIR=$(ASTDATADIR)/firmware
+ ASTCFLAGS=
+
+@@ -542,38 +544,38 @@
+
datafiles: all
if [ x`$(ID) -un` = xroot ]; then sh mkpkgconfig $(DESTDIR)/usr/lib/pkgconfig; fi
- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/digits
@@ -175,7 +199,7 @@
else \
echo "No description for $$x"; \
exit 1; \
-@@ -578,16 +579,16 @@
+@@ -581,16 +583,16 @@
done
for x in sounds/demo-* sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-* sounds/conf-* sounds/agent-* sounds/invalid* sounds/tt-* sounds/auth-* sounds/privacy-* sounds/queue-* sounds/spy-* sounds/priv-* sounds/screen-* sounds/hello-*; do \
if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
@@ -196,7 +220,7 @@
done
mkdir -p $(DESTDIR)$(AGI_DIR)
-@@ -623,6 +624,7 @@
+@@ -626,6 +628,7 @@
mkdir -p $(DESTDIR)$(ASTETCDIR)
mkdir -p $(DESTDIR)$(ASTBINDIR)
mkdir -p $(DESTDIR)$(ASTVARRUNDIR)
@@ -204,7 +228,7 @@
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/dictate
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/system
-@@ -645,7 +647,7 @@
+@@ -648,12 +651,12 @@
if [ -n "$(OLDHEADERS)" ]; then \
rm -f $(addprefix $(DESTDIR)$(ASTHEADERDIR)/,$(OLDHEADERS)) ;\
fi
@@ -213,8 +237,24 @@
mkdir -p $(DESTDIR)$(ASTLOGDIR)/cdr-csv
mkdir -p $(DESTDIR)$(ASTLOGDIR)/cdr-custom
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/keys
-@@ -763,10 +765,10 @@
+- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/firmware
+- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/firmware/iax
++ mkdir -p $(DESTDIR)$(FIRMWARE_DIR)
++ mkdir -p $(DESTDIR)$(FIRMWARE_DIR)/iax
+ mkdir -p $(DESTDIR)$(ASTMANDIR)/man8
+ $(INSTALL) -m 644 keys/iaxtel.pub $(DESTDIR)$(ASTVARLIBDIR)/keys
+ $(INSTALL) -m 644 keys/freeworlddialup.pub $(DESTDIR)$(ASTVARLIBDIR)/keys
+@@ -662,7 +665,7 @@
+ $(INSTALL) -m 644 contrib/scripts/autosupport.8 $(DESTDIR)$(ASTMANDIR)/man8
+ $(INSTALL) -m 644 contrib/scripts/safe_asterisk.8 $(DESTDIR)$(ASTMANDIR)/man8
+ if [ -d contrib/firmware/iax ]; then \
+- $(INSTALL) -m 644 contrib/firmware/iax/iaxy.bin $(DESTDIR)$(ASTVARLIBDIR)/firmware/iax/iaxy.bin; \
++ $(INSTALL) -m 644 contrib/firmware/iax/iaxy.bin $(DESTDIR)$(FIRMWARE_DIR)/iax/iaxy.bin; \
else \
+ echo "You need to do cvs update -d not just cvs update" ; \
+ fi
+@@ -764,10 +767,10 @@
+ else \
echo "Skipping asterisk.conf creation"; \
fi
- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
@@ -226,7 +266,7 @@
else \
echo "No description for $$x"; \
exit 1; \
-@@ -780,11 +782,11 @@
+@@ -781,11 +784,11 @@
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/INBOX
:> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/unavail.gsm
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
Added: asterisk/branches/sarge/debian/patches/brazilian_syntax.dpatch
===================================================================
--- asterisk/branches/sarge/debian/patches/brazilian_syntax.dpatch 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/patches/brazilian_syntax.dpatch 2006-05-16 10:42:26 UTC (rev 1767)
@@ -0,0 +1,535 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## brazilian_syntax.dpatch by Celso Fassoni <celso.fassoni at gmail.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Brazilian portuguese syntax for VoiceMail() and Say* apps
+## DP: at Wed Apr 26 17:25:54 BRT 2006
+
+ at DPATCH@
+diff -urNad asterisk-1.2.6.dfsg/ asterisk-1.2.6.dfsg.new/
+--- asterisk-1.2.6.dfsg/apps/app_sayunixtime.c 2006-05-15 11:26:14.778183712 -0300
++++ asterisk-1.2.6.dfsg.new/apps/app_sayunixtime.c 2006-05-15 11:26:19.002541512 -0300
+@@ -85,6 +85,8 @@
+ format = "A dBY HMS";
+ } else if ( !strcasecmp(chan->language, "de" ) ) {
+ format = "A dBY HMS";
++ } else if ( !strcasecmp(chan->language, "br" ) ) {
++ format = "Ad 'digits/pt-de' B 'digits/pt-de' Y 'digits/pt-as' HMS";
+ } else {
+ format = "ABdY 'digits/at' IMp";
+ }
+--- asterisk-1.2.6.dfsg/apps/app_voicemail.c 2006-05-15 11:11:54.159017712 -0300
++++ asterisk-1.2.6.dfsg.new/apps/app_voicemail.c 2006-05-15 11:11:58.390374448 -0300
+@@ -144,6 +144,7 @@
+ /*! \page vmlang Voicemail Language Syntaxes Supported
+
+ \par Syntaxes supported, not really language codes.
++ \arg \b br - Brazilian Portuguese
+ \arg \b en - English
+ \arg \b de - German
+ \arg \b es - Spanish
+@@ -3669,6 +3670,8 @@
+ res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' 'digits/hours' k 'digits/e' M 'digits/minutes'", NULL);
+ else if (!strcasecmp(chan->language,"gr"))
+ res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL);
++ else if (!strcasecmp(chan->language,"br"))
++ res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'digits/pt-de' B 'digits/pt-de' Y 'digits/pt-as' HM ", NULL);
+ else
+ res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
+ #if 0
+@@ -3965,7 +3968,7 @@
+ {
+ int cmd;
+
+- if (!strcasecmp(chan->language, "it") || !strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "fr") || !strcasecmp(chan->language, "pt")) { /* Italian, Spanish, French or Portuguese syntax */
++ if (!strcasecmp(chan->language, "it") || !strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "fr") || !strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "br")) { /* Italian, Spanish, French or Portuguese syntax */
+ cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
+ if (cmd)
+ return cmd;
+@@ -4297,6 +4300,54 @@
+ return res;
+ }
+
++/* BRAZILIAN PORTUGUESE syntax */
++static int vm_intro_br(struct ast_channel *chan,struct vm_state *vms) {
++ /* Introduce messages they have */
++ int res;
++ if (!vms->oldmessages && !vms->newmessages) {
++ res = ast_play_and_wait(chan, "vm-nomessages");
++ return res;
++ }
++ else {
++ res = ast_play_and_wait(chan, "vm-youhave");
++ }
++ if (vms->newmessages) {
++ if (!res)
++ res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
++ if ((vms->newmessages == 1)) {
++ if (!res)
++ res = ast_play_and_wait(chan, "vm-message");
++ if (!res)
++ res = ast_play_and_wait(chan, "vm-INBOXs");
++ }
++ else {
++ if (!res)
++ res = ast_play_and_wait(chan, "vm-messages");
++ if (!res)
++ res = ast_play_and_wait(chan, "vm-INBOX");
++ }
++ if (vms->oldmessages && !res)
++ res = ast_play_and_wait(chan, "vm-and");
++ }
++ if (vms->oldmessages) {
++ if (!res)
++ res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
++ if (vms->oldmessages == 1) {
++ if (!res)
++ res = ast_play_and_wait(chan, "vm-message");
++ if (!res)
++ res = ast_play_and_wait(chan, "vm-Olds");
++ }
++ else {
++ if (!res)
++ res = ast_play_and_wait(chan, "vm-messages");
++ if (!res)
++ res = ast_play_and_wait(chan, "vm-Old");
++ }
++ }
++ return res;
++}
++
+ /* FRENCH syntax */
+ static int vm_intro_fr(struct ast_channel *chan,struct vm_state *vms)
+ {
+@@ -4530,6 +4581,8 @@
+ return vm_intro_nl(chan, vms);
+ } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */
+ return vm_intro_pt(chan, vms);
++ } else if (!strcasecmp(chan->language, "br")) { /* BRAZILIAN PORTUGUESE syntax */
++ return vm_intro_br(chan, vms);
+ } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */
+ return vm_intro_cz(chan, vms);
+ } else if (!strcasecmp(chan->language, "gr")) { /* GREEK syntax */
+@@ -4938,7 +4991,7 @@
+ return vm_browse_messages_es(chan, vms, vmu);
+ } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN */
+ return vm_browse_messages_it(chan, vms, vmu);
+- } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE */
++ } else if (!strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "br")) { /* PORTUGUESE */
+ return vm_browse_messages_pt(chan, vms, vmu);
+ } else if (!strcasecmp(chan->language, "gr")){
+ return vm_browse_messages_gr(chan, vms, vmu); /* GREEK */
+--- asterisk-1.2.6.dfsg/say.c 2006-05-15 11:11:46.544175344 -0300
++++ asterisk-1.2.6.dfsg.new/say.c 2006-05-15 11:12:01.613884400 -0300
+@@ -384,6 +384,7 @@
+ static int ast_say_time_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+ static int ast_say_time_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+ static int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
++static int ast_say_time_br(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+ static int ast_say_time_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+ static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+
+@@ -392,6 +393,7 @@
+ static int ast_say_datetime_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+ static int ast_say_datetime_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+ static int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
++static int ast_say_datetime_br(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+ static int ast_say_datetime_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+ static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+
+@@ -437,7 +439,7 @@
+ return(ast_say_number_full_nl(chan, num, ints, language, audiofd, ctrlfd));
+ } else if (!strcasecmp(language, "pl") ) { /* Polish syntax */
+ return(ast_say_number_full_pl(chan, num, ints, language, options, audiofd, ctrlfd));
+- } else if (!strcasecmp(language, "pt") ) { /* Portuguese syntax */
++ } else if (!strcasecmp(language, "pt") || !strcasecmp(language, "br")) { /* Portuguese syntax */
+ return(ast_say_number_full_pt(chan, num, ints, language, options, audiofd, ctrlfd));
+ } else if (!strcasecmp(language, "se") ) { /* Swedish syntax */
+ return(ast_say_number_full_se(chan, num, ints, language, options, audiofd, ctrlfd));
+@@ -2006,6 +2008,10 @@
+ (!(num % 1000) && (((num / 1000) % 1000) < 100 || !((num / 1000) % 100))) ) )
+ playh = 1;
+ num = num % 1000000;
++ } else {
++ /** Protection: number is to big **/
++ ast_log(LOG_WARNING, "Number '%d' is too big to say.", num);
++ res = -1;
+ }
+ if (!res) {
+ if (!ast_streamfile(chan, fn, language)) {
+@@ -2728,7 +2734,7 @@
+ return(ast_say_date_fr(chan, t, ints, lang));
+ } else if (!strcasecmp(lang, "nl") ) { /* Dutch syntax */
+ return(ast_say_date_nl(chan, t, ints, lang));
+- } else if (!strcasecmp(lang, "pt") ) { /* Portuguese syntax */
++ } else if (!strcasecmp(lang, "pt") || !strcasecmp(lang, "br")) { /* Portuguese syntax */
+ return(ast_say_date_pt(chan, t, ints, lang));
+ } else if (!strcasecmp(lang, "gr") ) { /* Greek syntax */
+ return(ast_say_date_gr(chan, t, ints, lang));
+@@ -2963,7 +2969,7 @@
+ return(ast_say_date_with_format_it(chan, time, ints, lang, format, timezone));
+ } else if (!strcasecmp(lang, "nl") ) { /* Dutch syntax */
+ return(ast_say_date_with_format_nl(chan, time, ints, lang, format, timezone));
+- } else if (!strcasecmp(lang, "pt") ) { /* Portuguese syntax */
++ } else if (!strcasecmp(lang, "pt") || !strcasecmp(lang, "br")) { /* Portuguese syntax */
+ return(ast_say_date_with_format_pt(chan, time, ints, lang, format, timezone));
+ } else if (!strcasecmp(lang, "tw") ) { /* Taiwanese syntax */
+ return(ast_say_date_with_format_tw(chan, time, ints, lang, format, timezone));
+@@ -3835,8 +3841,12 @@
+ break;
+ case 'm':
+ /* First - Twelfth */
+- snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
+- res = wait_file(chan,ints,nextmsg,lang);
++ if (!strcasecmp(lang, "br")) {
++ res = ast_say_number(chan, tm.tm_mon+1, ints, lang, (char *) NULL);
++ } else {
++ snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
++ res = wait_file(chan,ints,nextmsg,lang);
++ }
+ break;
+ case 'd':
+ case 'e':
+@@ -4671,66 +4681,126 @@
+ case 'I':
+ case 'l':
+ /* 12-Hour */
+- if (tm.tm_hour == 0) {
+- if (format[offset] == 'I')
+- res = wait_file(chan, ints, "digits/pt-ah", lang);
+- if (!res)
+- res = wait_file(chan, ints, "digits/pt-meianoite", lang);
+- }
+- else if (tm.tm_hour == 12) {
+- if (format[offset] == 'I')
+- res = wait_file(chan, ints, "digits/pt-ao", lang);
+- if (!res)
+- res = wait_file(chan, ints, "digits/pt-meiodia", lang);
+- }
+- else {
+- if (format[offset] == 'I') {
+- res = wait_file(chan, ints, "digits/pt-ah", lang);
+- if ((tm.tm_hour % 12) != 1)
+- if (!res)
+- res = wait_file(chan, ints, "digits/pt-sss", lang);
+- }
+- if (!res)
+- res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
++ if (!strcasecmp(lang, "br")) {
++ if (tm.tm_hour == 0) {
++ if (format[offset] == 'I')
++ res = wait_file(chan, ints, "digits/pt-a", lang);
++ if (!res)
++ res = wait_file(chan, ints, "digits/pt-meianoite", lang);
++ } else if (tm.tm_hour == 12) {
++ if (format[offset] == 'I')
++ res = wait_file(chan, ints, "digits/pt-ao", lang);
++ if (!res)
++ res = wait_file(chan, ints, "digits/pt-meiodia", lang);
++ } else {
++ if (format[offset] == 'I') {
++ if ((tm.tm_hour % 12) != 1)
++ res = wait_file(chan, ints, "digits/pt-as", lang);
++ else
++ res = wait_file(chan, ints, "digits/pt-a", lang);
++ }
++ if (!res)
++ res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
++ if ((!res) && (format[offset] == 'I'))
++ res = ast_say_date_with_format(chan, time, ints, lang, "P", timezone);
++ }
++ } else {
++ if (tm.tm_hour == 0) {
++ if (format[offset] == 'I')
++ res = wait_file(chan, ints, "digits/pt-ah", lang);
++ if (!res)
++ res = wait_file(chan, ints, "digits/pt-meianoite", lang);
++ }
++ else if (tm.tm_hour == 12) {
++ if (format[offset] == 'I')
++ res = wait_file(chan, ints, "digits/pt-ao", lang);
++ if (!res)
++ res = wait_file(chan, ints, "digits/pt-meiodia", lang);
++ }
++ else {
++ if (format[offset] == 'I') {
++ res = wait_file(chan, ints, "digits/pt-ah", lang);
++ if ((tm.tm_hour % 12) != 1)
++ if (!res)
++ res = wait_file(chan, ints, "digits/pt-sss", lang);
++ }
++ if (!res)
++ res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
++ }
+ }
+ break;
+ case 'H':
+ case 'k':
+ /* 24-Hour */
+- res = ast_say_number(chan, -tm.tm_hour, ints, lang, NULL);
+- if (!res) {
+- if (tm.tm_hour != 0) {
+- int remainder = tm.tm_hour;
+- if (tm.tm_hour > 20) {
+- res = wait_file(chan,ints, "digits/20",lang);
+- remainder -= 20;
++ if (!strcasecmp(lang, "br")) {
++ res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
++ if ((!res) && (format[offset] == 'H')) {
++ if (tm.tm_hour > 1) {
++ res = wait_file(chan,ints,"digits/hours",lang);
++ } else {
++ res = wait_file(chan,ints,"digits/hour",lang);
+ }
+- if (!res) {
+- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", remainder);
+- res = wait_file(chan,ints,nextmsg,lang);
++ }
++ } else {
++ res = ast_say_number(chan, -tm.tm_hour, ints, lang, NULL);
++ if (!res) {
++ if (tm.tm_hour != 0) {
++ int remainder = tm.tm_hour;
++ if (tm.tm_hour > 20) {
++ res = wait_file(chan,ints, "digits/20",lang);
++ remainder -= 20;
++ }
++ if (!res) {
++ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", remainder);
++ res = wait_file(chan,ints,nextmsg,lang);
++ }
+ }
+ }
+ }
+ break;
+ case 'M':
+ /* Minute */
+- if (tm.tm_min == 0) {
+- res = wait_file(chan, ints, "digits/pt-hora", lang);
+- if (tm.tm_hour != 1)
++ if (!strcasecmp(lang, "br")) {
++ res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
++ if (!res) {
++ if (tm.tm_min > 1) {
++ res = wait_file(chan,ints,"digits/minutes",lang);
++ } else {
++ res = wait_file(chan,ints,"digits/minute",lang);
++ }
++ }
++ } else {
++ if (tm.tm_min == 0) {
++ res = wait_file(chan, ints, "digits/pt-hora", lang);
++ if (tm.tm_hour != 1)
++ if (!res)
++ res = wait_file(chan, ints, "digits/pt-sss", lang); } else {
++ res = wait_file(chan,ints,"digits/pt-e",lang);
+ if (!res)
+- res = wait_file(chan, ints, "digits/pt-sss", lang); } else {
+- res = wait_file(chan,ints,"digits/pt-e",lang);
+- if (!res)
+- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
++ res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
++ }
+ }
+ break;
+ case 'P':
+ case 'p':
+ /* AM/PM */
+- if (tm.tm_hour > 12)
+- res = wait_file(chan, ints, "digits/p-m", lang);
+- else if (tm.tm_hour && tm.tm_hour < 12)
+- res = wait_file(chan, ints, "digits/a-m", lang);
++ if (!strcasecmp(lang, "br")) {
++ if ((tm.tm_hour != 0) && (tm.tm_hour != 12)) {
++ res = wait_file(chan, ints, "digits/pt-da", lang);
++ if (!res) {
++ if ((tm.tm_hour >= 0) && (tm.tm_hour < 12))
++ res = wait_file(chan, ints, "digits/morning", lang);
++ else if ((tm.tm_hour >= 12) && (tm.tm_hour < 18))
++ res = wait_file(chan, ints, "digits/afternoon", lang);
++ else res = wait_file(chan, ints, "digits/night", lang);
++ }
++ }
++ } else {
++ if (tm.tm_hour > 12)
++ res = wait_file(chan, ints, "digits/p-m", lang);
++ else if (tm.tm_hour && tm.tm_hour < 12)
++ res = wait_file(chan, ints, "digits/a-m", lang);
++ }
+ break;
+ case 'Q':
+ /* Shorthand for "Today", "Yesterday", or ABdY */
+@@ -4785,30 +4855,41 @@
+ break;
+ case 'S':
+ /* Seconds */
+- if (tm.tm_sec == 0) {
+- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
+- res = wait_file(chan,ints,nextmsg,lang);
+- } else if (tm.tm_sec < 10) {
+- res = wait_file(chan,ints, "digits/oh",lang);
++ if (!strcasecmp(lang, "br")) {
++ res = ast_say_number(chan, tm.tm_sec, ints, lang, NULL);
+ if (!res) {
+- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
+- res = wait_file(chan,ints,nextmsg,lang);
++ if (tm.tm_sec > 1) {
++ res = wait_file(chan,ints,"digits/seconds",lang);
++ } else {
++ res = wait_file(chan,ints,"digits/second",lang);
++ }
+ }
+- } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
+- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
+- res = wait_file(chan,ints,nextmsg,lang);
+ } else {
+- int ten, one;
+- ten = (tm.tm_sec / 10) * 10;
+- one = (tm.tm_sec % 10);
+- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
+- res = wait_file(chan,ints,nextmsg,lang);
+- if (!res) {
+- /* Fifty, not fifty-zero */
+- if (one != 0) {
+- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
++ if (tm.tm_sec == 0) {
++ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
++ res = wait_file(chan,ints,nextmsg,lang);
++ } else if (tm.tm_sec < 10) {
++ res = wait_file(chan,ints, "digits/oh",lang);
++ if (!res) {
++ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
+ res = wait_file(chan,ints,nextmsg,lang);
+ }
++ } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
++ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
++ res = wait_file(chan,ints,nextmsg,lang);
++ } else {
++ int ten, one;
++ ten = (tm.tm_sec / 10) * 10;
++ one = (tm.tm_sec % 10);
++ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
++ res = wait_file(chan,ints,nextmsg,lang);
++ if (!res) {
++ /* Fifty, not fifty-zero */
++ if (one != 0) {
++ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
++ res = wait_file(chan,ints,nextmsg,lang);
++ }
++ }
+ }
+ }
+ break;
+@@ -5104,6 +5185,8 @@
+ return(ast_say_time_nl(chan, t, ints, lang));
+ } else if (!strcasecmp(lang, "pt") ) { /* Portuguese syntax */
+ return(ast_say_time_pt(chan, t, ints, lang));
++ } else if (!strcasecmp(lang, "br") ) { /* Brazilian Portuguese syntax */
++ return(ast_say_time_br(chan, t, ints, lang));
+ } else if (!strcasecmp(lang, "tw") ) { /* Taiwanese syntax */
+ return(ast_say_time_tw(chan, t, ints, lang));
+ } else if (!strcasecmp(lang, "gr") ) { /* Greek syntax */
+@@ -5241,6 +5324,34 @@
+ return res;
+ }
+
++/* Brazilian Portuguese syntax */
++int ast_say_time_br(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
++{
++ struct tm tm;
++ int res = 0;
++ localtime_r(&t,&tm);
++
++ res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
++ if (!res) {
++ if (tm.tm_hour > 1)
++ res = wait_file(chan, ints, "digits/hours", lang);
++ else
++ res = wait_file(chan, ints, "digits/hour", lang);
++ }
++ if ((!res) && (tm.tm_min)) {
++ res = wait_file(chan, ints, "digits/pt-e", lang);
++ if (!res)
++ res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
++ if (!res) {
++ if (tm.tm_min > 1)
++ res = wait_file(chan, ints, "digits/minutes", lang);
++ else
++ res = wait_file(chan, ints, "digits/minute", lang);
++ }
++ }
++ return res;
++}
++
+ /* Taiwanese syntax */
+ int ast_say_time_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+ {
+@@ -5293,6 +5404,8 @@
+ return(ast_say_datetime_nl(chan, t, ints, lang));
+ } else if (!strcasecmp(lang, "pt") ) { /* Portuguese syntax */
+ return(ast_say_datetime_pt(chan, t, ints, lang));
++ } else if (!strcasecmp(lang, "br") ) { /* Brazilian Portuguese syntax */
++ return(ast_say_datetime_br(chan, t, ints, lang));
+ } else if (!strcasecmp(lang, "tw") ) { /* Taiwanese syntax */
+ return(ast_say_datetime_tw(chan, t, ints, lang));
+ } else if (!strcasecmp(lang, "gr") ) { /* Greek syntax */
+@@ -5502,6 +5615,18 @@
+ return res;
+ }
+
++/* Brazilian Portuguese syntax */
++int ast_say_datetime_br(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
++{
++ struct tm tm;
++ int res = 0;
++ localtime_r(&t,&tm);
++ res = ast_say_date(chan, t, ints, lang);
++ if (!res)
++ res = ast_say_time(chan, t, ints, lang);
++ return res;
++}
++
+ /* Taiwanese syntax */
+ int ast_say_datetime_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+ {
+@@ -5566,7 +5691,7 @@
+ return(ast_say_datetime_from_now_en(chan, t, ints, lang));
+ } else if (!strcasecmp(lang, "fr") ) { /* French syntax */
+ return(ast_say_datetime_from_now_fr(chan, t, ints, lang));
+- } else if (!strcasecmp(lang, "pt") ) { /* Portuguese syntax */
++ } else if (!strcasecmp(lang, "pt") || !strcasecmp(lang, "br")) { /* Portuguese syntax */
+ return(ast_say_datetime_from_now_pt(chan, t, ints, lang));
+ }
+
+@@ -5685,14 +5810,24 @@
+ if (!res)
+ res = wait_file(chan, ints, fn, lang);
+ } /* Otherwise, it was today */
+- snprintf(fn, sizeof(fn), "digits/pt-ah");
+- if (!res)
+- res = wait_file(chan, ints, fn, lang);
+- if (tm.tm_hour != 1)
+- if (!res)
+- res = wait_file(chan, ints, "digits/pt-sss", lang);
+- if (!res)
+- res = ast_say_time(chan, t, ints, lang);
++ if (!strcasecmp(lang, "br")) {
++ if (tm.tm_hour > 1) {
++ snprintf(fn, sizeof(fn), "digits/pt-as");
++ } else {
++ snprintf(fn, sizeof(fn), "digits/pt-a");
++ }
++ if (!res)
++ res = wait_file(chan, ints, fn, lang);
++ } else {
++ snprintf(fn, sizeof(fn), "digits/pt-ah");
++ if (!res)
++ res = wait_file(chan, ints, fn, lang);
++ if (tm.tm_hour != 1)
++ if (!res)
++ res = wait_file(chan, ints, "digits/pt-sss", lang);
++ if (!res)
++ res = ast_say_time(chan, t, ints, lang);
++ }
+ return res;
+ }
Added: asterisk/branches/sarge/debian/patches/func_odbc_12.dpatch
===================================================================
--- asterisk/branches/sarge/debian/patches/func_odbc_12.dpatch 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/patches/func_odbc_12.dpatch 2006-05-16 10:42:26 UTC (rev 1767)
@@ -0,0 +1,908 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## func_odbc_12.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: The backport of func_odbc from
+## DP: http://svncommunity.digium.com/svn/func_odbc/1.2/ , revision 9
+## DP: Code will be merged into trunk in 1.4.
+
+ at DPATCH@
+diff -urNad asterisk-1.2.7.1.dfsg/configs/func_odbc.conf.sample /tmp/dpep.PgBRQP/asterisk-1.2.7.1.dfsg/configs/func_odbc.conf.sample
+--- asterisk-1.2.7.1.dfsg/configs/func_odbc.conf.sample 1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.PgBRQP/asterisk-1.2.7.1.dfsg/configs/func_odbc.conf.sample 2006-05-16 11:04:22.885412107 +0300
+@@ -0,0 +1,38 @@
++;
++; func_odbc.conf
++;
++; Each context is a separately defined function. By convention, all
++; functions are entirely uppercase, so the defined contexts should also
++; be all-uppercase, but there is nothing that enforces this. All functions
++; are case-sensitive, however.
++;
++; For substitution, you have ${ARG1}, ${ARG2} ... ${ARGn}
++; for the arguments to each SQL statement.
++;
++; In addition, for write statements, you have ${VAL1}, ${VAL2} ... ${VALn}
++; parsed, just like arguments, for the values. In addition, if you want the
++; whole value, never mind the parsing, you can get that with ${VALUE}.
++;
++;
++; If you have data which may potentially contain single ticks, you may wish
++; to use the dialplan function SQL_ESC() to escape the data prior to its
++; inclusion in the SQL statement.
++
++
++; ODBC_SQL - Allow an SQL statement to be built entirely in the dialplan
++[SQL]
++dsn=mysql1
++read=${ARG1}
++
++; ODBC_ANTIGF - A blacklist.
++[ANTIGF]
++dsn=mysql1
++read=SELECT COUNT(*) FROM exgirlfriends WHERE callerid='${SQL_ESC(${ARG1})}'
++
++; ODBC_PRESENCE - Retrieve and update presence
++[PRESENCE]
++dsn=mysql1
++read=SELECT location FROM presence WHERE id='${SQL_ESC(${ARG1})}'
++write=UPDATE presence SET location='${SQL_ESC(${VAL1})}' WHERE id='${SQL_ESC(${ARG1})}'
++;prefix=OFFICE ; Changes this function from ODBC_PRESENCE to OFFICE_PRESENCE
++
+diff -urNad asterisk-1.2.7.1.dfsg/funcs/func_array.c /tmp/dpep.PgBRQP/asterisk-1.2.7.1.dfsg/funcs/func_array.c
+--- asterisk-1.2.7.1.dfsg/funcs/func_array.c 1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.PgBRQP/asterisk-1.2.7.1.dfsg/funcs/func_array.c 2006-05-16 11:00:46.455618304 +0300
+@@ -0,0 +1,191 @@
++/*
++ * Asterisk -- An open source telephony toolkit.
++ *
++ * Copyright (C) 2005, Tilghman Lesher.
++ *
++ * See http://www.asterisk.org for more information about
++ * the Asterisk project. Please do not directly contact
++ * any of the maintainers of this project for assistance;
++ * the project provides a web site, mailing lists and IRC
++ * channels for your use.
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License Version 2. See the LICENSE file
++ * at the top of the source tree.
++ */
++
++/*! \file
++ *
++ * \brief ARRAY dialplan function
++ *
++ * \author Tilghman Lesher
++ */
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <sys/types.h>
++#include <sched.h>
++
++#include "asterisk.h"
++
++ASTERISK_FILE_VERSION(__FILE__, "$Revision: 20003 $")
++
++#include "asterisk/module.h"
++#include "asterisk/channel.h"
++#include "asterisk/pbx.h"
++#include "asterisk/logger.h"
++#include "asterisk/utils.h"
++#include "asterisk/app.h"
++#include "asterisk/localtime.h"
++
++AST_MUTEX_DEFINE_STATIC(local_lock);
++static int use_count = 0;
++
++static unsigned int trunk_app_separate_args(char *buf, char delim, char **array, int arraylen)
++{
++ int argc;
++ char *scan;
++ int paren = 0, quote = 0;
++
++ if (!buf || !array || !arraylen)
++ return 0;
++
++ memset(array, 0, arraylen * sizeof(*array));
++
++ scan = buf;
++
++ for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
++ array[argc] = scan;
++ for (; *scan; scan++) {
++ if (*scan == '(')
++ paren++;
++ else if (*scan == ')') {
++ if (paren)
++ paren--;
++ } else if (*scan == '"') {
++ quote = quote ? 0 : 1;
++ /* Remove quote character from argument */
++ memmove(scan, scan + 1, strlen(scan));
++ scan--;
++ } else if (*scan == '\\') {
++ /* Literal character, don't parse */
++ memmove(scan, scan + 1, strlen(scan));
++ } else if ((*scan == delim) && !paren && !quote) {
++ *scan++ = '\0';
++ break;
++ }
++ }
++ }
++
++ if (*scan)
++ array[argc++] = scan;
++
++ return argc;
++}
++
++static void array(struct ast_channel *chan, char *cmd, char *var, const char *value)
++{
++ AST_DECLARE_APP_ARGS(arg1,
++ AST_APP_ARG(var)[100];
++ );
++ AST_DECLARE_APP_ARGS(arg2,
++ AST_APP_ARG(val)[100];
++ );
++ char *value2;
++ int i;
++
++ value2 = ast_strdupa(value);
++ if (!var || !value2)
++ return;
++
++ ast_mutex_lock(&local_lock);
++ use_count++;
++ ast_mutex_unlock(&local_lock);
++
++ /* The functions this will generally be used with are SORT and ODBC_*, which
++ * both return comma-delimited lists. However, if somebody uses literal lists,
++ * their commas will be translated to vertical bars by the load, and I don't
++ * want them to be surprised by the result. Hence, we prefer commas as the
++ * delimiter, but we'll fall back to vertical bars if commas aren't found.
++ */
++ ast_log(LOG_DEBUG, "array (%s=%s)\n", var, value2);
++ if (strchr(var, ','))
++ arg1.argc = trunk_app_separate_args(var, ',', arg1.argv, (sizeof(arg1) - sizeof(arg1.argc)) / sizeof(arg1.argv[0]));
++ else
++ arg1.argc = trunk_app_separate_args(var, '|', arg1.argv, (sizeof(arg1) - sizeof(arg1.argc)) / sizeof(arg1.argv[0]));
++
++ if (strchr(value2, ','))
++ arg2.argc = trunk_app_separate_args(value2, ',', arg2.argv, (sizeof(arg2) - sizeof(arg2.argc)) / sizeof(arg2.argv[0]));
++ else
++ arg2.argc = trunk_app_separate_args(value2, '|', arg2.argv, (sizeof(arg2) - sizeof(arg2.argc)) / sizeof(arg2.argv[0]));
++
++ for (i = 0; i < arg1.argc; i++) {
++ ast_log(LOG_DEBUG, "array set value (%s=%s)\n", arg1.var[i],
++ arg2.val[i]);
++ if (i < arg2.argc) {
++ pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]);
++ } else {
++ /* We could unset the variable, by passing a NULL, but due to
++ * pushvar semantics, that could create some undesired behavior. */
++ pbx_builtin_setvar_helper(chan, arg1.var[i], "");
++ }
++ }
++
++ ast_mutex_lock(&local_lock);
++ use_count--;
++ ast_mutex_unlock(&local_lock);
++
++ return;
++}
++
++static struct ast_custom_function array_function = {
++ .name = "ARRAY",
++ .synopsis = "Allows setting multiple variables at once",
++ .syntax = "ARRAY(var1[,var2[...][,varN]])",
++ .write = array,
++ .desc =
++ "The comma-separated list passed as a value to which the function is set will\n"
++ "be interpreted as a set of values to which the comma-separated list of\n"
++ "variable names in the argument should be set.\n"
++ "Hence, Set(ARRAY(var1,var2)=1,2) will set var1 to 1 and var2 to 2\n"
++ "Note: remember to either backslash your commas in extensions.conf or quote the\n"
++ "entire argument, since Set can take multiple arguments itself.\n",
++};
++
++static char *tdesc = "String handling dialplan functions";
++
++int unload_module(void)
++{
++ int res = 0;
++
++ res |= ast_custom_function_unregister(&array_function);
++ sched_yield(); /* Any remaining process gets time to clear out. Increases safety if a force unload is attempted. */
++
++ return res;
++}
++
++int load_module(void)
++{
++ int res = 0;
++
++ res |= ast_custom_function_register(&array_function);
++
++ return res;
++}
++
++char *description(void)
++{
++ return tdesc;
++}
++
++int usecount(void)
++{
++ return use_count;
++}
++
++char *key(void)
++{
++ return ASTERISK_GPL_KEY;
++}
++
+diff -urNad asterisk-1.2.7.1.dfsg/funcs/func_odbc.c /tmp/dpep.PgBRQP/asterisk-1.2.7.1.dfsg/funcs/func_odbc.c
+--- asterisk-1.2.7.1.dfsg/funcs/func_odbc.c 1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.PgBRQP/asterisk-1.2.7.1.dfsg/funcs/func_odbc.c 2006-05-16 11:01:01.417565099 +0300
+@@ -0,0 +1,658 @@
++/*
++ * Asterisk -- An open source telephony toolkit.
++ *
++ * Copyright (c) 2005 Tilghman Lesher
++ *
++ * Tilghman Lesher <func_odbc__200604 at the-tilghman.com>
++ *
++ * See http://www.asterisk.org for more information about
++ * the Asterisk project. Please do not directly contact
++ * any of the maintainers of this project for assistance;
++ * the project provides a web site, mailing lists and IRC
++ * channels for your use.
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License Version 2. See the LICENSE file
++ * at the top of the source tree.
++ */
++
++/*!
++ * \file
++ *
++ * \brief ODBC lookups
++ *
++ * \author Tilghman Lesher <func_odbc__200604 at the-tilghman.com>
++ */
++
++#include <sys/types.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++
++#include "asterisk.h"
++
++ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7 $")
++
++#include <asterisk/module.h>
++#include <asterisk/file.h>
++#include <asterisk/logger.h>
++#include <asterisk/options.h>
++#include <asterisk/channel.h>
++#include <asterisk/pbx.h>
++#include <asterisk/module.h>
++#include <asterisk/config.h>
++#include <asterisk/res_odbc.h>
++#include <asterisk/app.h>
++
++static char *tdesc = "ODBC lookups";
++
++static char *config = "func_odbc.conf";
++
++struct acf_odbc_query {
++ AST_LIST_ENTRY(acf_odbc_query) list;
++ char dsn[30];
++ char sql_read[2048];
++ char sql_write[2048];
++ struct ast_custom_function *acf;
++};
++
++AST_LIST_HEAD_STATIC(queries, acf_odbc_query);
++
++#ifdef NEEDTRACE
++static void acf_odbc_error(SQLHSTMT stmt, int res)
++{
++ char state[10] = "", diagnostic[256] = "";
++ SQLINTEGER nativeerror = 0;
++ SQLSMALLINT diagbytes = 0;
++ SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, state, &nativeerror, diagnostic, sizeof(diagnostic), &diagbytes);
++ ast_log(LOG_WARNING, "SQL return value %d: error %s: %s (len %d)\n", res, state, diagnostic, diagbytes);
++}
++#endif
++
++/*
++ * Master control routine
++ */
++static void acf_odbc_write(struct ast_channel *chan, char *cmd, char *data, const char *value)
++{
++ odbc_obj *obj;
++ struct acf_odbc_query *query;
++ char *s, *t, *arg, buf[2048]="", varname[15];
++ int res, argcount=0, valcount=0, i, retry=0;
++ struct ast_channel *ast;
++ SQLHSTMT stmt;
++ SQLINTEGER nativeerror=0, numfields=0, rows=0;
++ SQLSMALLINT diagbytes=0;
++ unsigned char state[10], diagnostic[256];
++#ifdef NEEDTRACE
++ SQLINTEGER enable = 1;
++ char *tracefile = "/tmp/odbc.trace";
++#endif
++
++ AST_LIST_LOCK(&queries);
++ AST_LIST_TRAVERSE(&queries, query, list) {
++ if (!strcmp(query->acf->name, cmd)) {
++ break;
++ }
++ }
++
++ if (!query) {
++ ast_log(LOG_ERROR, "No such function '%s'\n", cmd);
++ AST_LIST_UNLOCK(&queries);
++ return;
++ }
++
++ obj = fetch_odbc_obj(query->dsn, 0);
++
++ if (!obj) {
++ ast_log(LOG_ERROR, "No such DSN registered: %s (check res_odbc.conf)\n", query->dsn);
++ AST_LIST_UNLOCK(&queries);
++ return;
++ }
++
++ /* Parse our arguments */
++ s = ast_strdupa(data);
++ if (value) {
++ t = ast_strdupa(value);
++ } else {
++ t = "";
++ }
++
++ if (!s || !t) {
++ ast_log(LOG_ERROR, "Out of memory\n");
++ AST_LIST_UNLOCK(&queries);
++ return;
++ }
++
++ /* XXX You might be tempted to change this section into using
++ * pbx_builtin_pushvar_helper(). However, note that if you try
++ * to set a NULL (like for VALUE), then nothing gets set, and the
++ * value doesn't get masked out. Even worse, when you subsequently
++ * try to remove the value you just set, you'll wind up unsetting
++ * the previous value (which is wholly undesireable). Hence, this
++ * has to remain the way it is done here. XXX
++ */
++
++ /* Save old arguments as variables in a fake channel */
++ ast = ast_channel_alloc(0);
++ while ((arg = strsep(&s, "|"))) {
++ argcount++;
++ snprintf(varname, sizeof(varname), "ARG%d", argcount);
++ pbx_builtin_setvar_helper(ast, varname, pbx_builtin_getvar_helper(chan, varname));
++ pbx_builtin_setvar_helper(chan, varname, arg);
++ }
++
++ /* Parse values, just like arguments */
++ while ((arg = strsep(&t, "|"))) {
++ valcount++;
++ snprintf(varname, sizeof(varname), "VAL%d", valcount);
++ pbx_builtin_setvar_helper(ast, varname, pbx_builtin_getvar_helper(chan, varname));
++ pbx_builtin_setvar_helper(chan, varname, arg);
++ }
++
++ /* Additionally set the value as a whole */
++ /* Note that pbx_builtin_setvar_helper will quite happily take a NULL for the 3rd argument */
++ pbx_builtin_setvar_helper(ast, "VALUE", pbx_builtin_getvar_helper(chan, "VALUE"));
++ pbx_builtin_setvar_helper(chan, "VALUE", value);
++
++ pbx_substitute_variables_helper(chan, query->sql_write, buf, sizeof(buf) - 1);
++
++ /* Restore prior values */
++ for (i=1; i<=argcount; i++) {
++ snprintf(varname, sizeof(varname), "ARG%d", argcount);
++ pbx_builtin_setvar_helper(chan, varname, pbx_builtin_getvar_helper(ast, varname));
++ }
++
++ for (i=1; i<=valcount; i++) {
++ snprintf(varname, sizeof(varname), "VAL%d", argcount);
++ pbx_builtin_setvar_helper(chan, varname, pbx_builtin_getvar_helper(ast, varname));
++ }
++ pbx_builtin_setvar_helper(chan, "VALUE", pbx_builtin_getvar_helper(ast, "VALUE"));
++
++ ast_channel_free(ast);
++ AST_LIST_UNLOCK(&queries);
++
++retry_write:
++#ifdef NEEDTRACE
++ SQLSetConnectAttr(obj->con, SQL_ATTR_TRACE, &enable, SQL_IS_INTEGER);
++ SQLSetConnectAttr(obj->con, SQL_ATTR_TRACEFILE, tracefile, strlen(tracefile));
++#endif
++
++ res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt);
++ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
++ ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
++ pbx_builtin_setvar_helper(chan, "ODBCROWS", "-1");
++ return;
++ }
++
++ res = SQLPrepare(stmt, (unsigned char *)buf, SQL_NTS);
++ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
++ ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", buf);
++ SQLFreeHandle (SQL_HANDLE_STMT, stmt);
++ pbx_builtin_setvar_helper(chan, "ODBCROWS", "-1");
++ return;
++ }
++
++ res = SQLExecute(stmt);
++ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
++ if (res == SQL_ERROR) {
++ SQLGetDiagField(SQL_HANDLE_STMT, stmt, 1, SQL_DIAG_NUMBER, &numfields, SQL_IS_INTEGER, &diagbytes);
++ for (i = 0; i <= numfields; i++) {
++ SQLGetDiagRec(SQL_HANDLE_STMT, stmt, i + 1, state, &nativeerror, diagnostic, sizeof(diagnostic), &diagbytes);
++ ast_log(LOG_WARNING, "SQL Execute returned an error %d: %s: %s (%d)\n", res, state, diagnostic, diagbytes);
++ if (i > 10) {
++ ast_log(LOG_WARNING, "Oh, that was good. There are really %d diagnostics?\n", (int)numfields);
++ break;
++ }
++ }
++ }
++ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
++ odbc_obj_disconnect(obj);
++ /* All handles are now invalid (after a disconnect), so we gotta redo all handles */
++ odbc_obj_connect(obj);
++ if (!retry) {
++ retry = 1;
++ goto retry_write;
++ }
++ rows = -1;
++ } else {
++ /* Rows affected */
++ SQLRowCount(stmt, &rows);
++ }
++
++ /* Output the affected rows, for all cases. In the event of failure, we
++ * flag this as -1 rows. Note that this is different from 0 affected rows
++ * which would be the case if we succeeded in our query, but the values did
++ * not change. */
++ snprintf(varname, sizeof(varname), "%d", (int)rows);
++ pbx_builtin_setvar_helper(chan, "ODBCROWS", varname);
++
++ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
++ ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", buf);
++ }
++
++ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
++}
++
++static char *acf_odbc_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
++{
++ odbc_obj *obj;
++ struct acf_odbc_query *query;
++ char *s, *arg, sql[2048] = "", varname[15];
++ int count=0, res, x, buflen = 0;
++ SQLHSTMT stmt;
++ SQLSMALLINT colcount=0;
++ SQLINTEGER indicator;
++#ifdef NEEDTRACE
++ SQLINTEGER enable = 1;
++ char *tracefile = "/tmp/odbc.trace";
++#endif
++
++ AST_LIST_LOCK(&queries);
++ AST_LIST_TRAVERSE(&queries, query, list) {
++ if (!strcmp(query->acf->name, cmd)) {
++ break;
++ }
++ }
++
++ if (!query) {
++ ast_log(LOG_ERROR, "No such function '%s'\n", cmd);
++ AST_LIST_UNLOCK(&queries);
++ return "";
++ }
++
++ obj = fetch_odbc_obj(query->dsn, 0);
++
++ if (!obj) {
++ ast_log(LOG_ERROR, "No such DSN registered: %s (check res_odbc.conf)\n", query->dsn);
++ AST_LIST_UNLOCK(&queries);
++ return "";
++ }
++
++#ifdef NEEDTRACE
++ SQLSetConnectAttr(obj->con, SQL_ATTR_TRACE, &enable, SQL_IS_INTEGER);
++ SQLSetConnectAttr(obj->con, SQL_ATTR_TRACEFILE, tracefile, strlen(tracefile));
++#endif
++
++ /* Parse our arguments */
++ if (!(s = ast_strdupa(data))) {
++ AST_LIST_UNLOCK(&queries);
++ return "";
++ }
++
++ while ((arg = strsep(&s, "|"))) {
++ count++;
++ snprintf(varname, sizeof(varname), "ARG%d", count);
++ /* arg is by definition non-NULL, so this works, here */
++ pbx_builtin_pushvar_helper(chan, varname, arg);
++ }
++
++ pbx_substitute_variables_helper(chan, query->sql_read, sql, sizeof(sql) - 1);
++
++ /* Restore prior values */
++ for (x = 1; x <= count; x++) {
++ snprintf(varname, sizeof(varname), "ARG%d", x);
++ pbx_builtin_setvar_helper(chan, varname, NULL);
++ }
++
++ AST_LIST_UNLOCK(&queries);
++
++ res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt);
++ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
++ ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
++ return "";
++ }
++
++ res = SQLPrepare(stmt, (unsigned char *)sql, SQL_NTS);
++ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
++ ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
++ SQLFreeHandle (SQL_HANDLE_STMT, stmt);
++ return "";
++ }
++
++ res = odbc_smart_execute(obj, stmt);
++ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
++ ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
++ SQLFreeHandle (SQL_HANDLE_STMT, stmt);
++ return "";
++ }
++
++ res = SQLNumResultCols(stmt, &colcount);
++ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
++ ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
++ SQLFreeHandle (SQL_HANDLE_STMT, stmt);
++ return "";
++ }
++
++ memset(buf, 0, len);
++
++ res = SQLFetch(stmt);
++ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
++ if (res == SQL_NO_DATA) {
++ if (option_verbose > 3) {
++ ast_verbose(VERBOSE_PREFIX_4 "Found no rows [%s]\n", sql);
++ }
++ } else if (option_verbose > 3) {
++ ast_log(LOG_WARNING, "Error %d in FETCH [%s]\n", res, sql);
++ }
++ goto acf_out;
++ }
++
++ for (x = 0; x < colcount; x++) {
++ int i;
++ char coldata[256];
++
++ buflen = strlen(buf);
++ res = SQLGetData(stmt, x + 1, SQL_CHAR, coldata, sizeof(coldata), &indicator);
++ if (indicator == SQL_NULL_DATA) {
++ coldata[0] = '\0';
++ res = SQL_SUCCESS;
++ }
++
++ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
++ ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
++ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
++ return "";
++ }
++
++ /* Copy data, encoding '\' and ',' for the argument parser */
++ for (i = 0; i < sizeof(coldata); i++) {
++ if (coldata[i] == '\\' || coldata[i] == ',') {
++ buf[buflen++] = '\\';
++ }
++ buf[buflen++] = coldata[i];
++
++ if (buflen >= len - 2) {
++ buf[buflen >= len ? len - 1 : buflen] = '\0';
++ break;
++ }
++
++ if (coldata[i] == '\0')
++ break;
++ }
++
++ buf[buflen - 1] = ',';
++ }
++ /* Trim trailing comma */
++ buf[buflen - 1] = '\0';
++
++acf_out:
++ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
++ return buf;
++}
++
++static char *acf_escape(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
++{
++ char *in, *out = buf;
++ for (in = data; *in && out - buf < len; in++) {
++ if (*in == '\'') {
++ *out = '\'';
++ out++;
++ }
++ *out = *in;
++ out++;
++ }
++ *out = '\0';
++ return buf;
++}
++
++static struct ast_custom_function escape_function = {
++ .name = "SQL_ESC",
++ .synopsis = "Escapes single ticks for use in SQL statements",
++ .syntax = "SQL_ESC(<string>)",
++ .desc =
++"Used in SQL templates to escape data which may contain single ticks (') which\n"
++"are otherwise used to delimit data. For example:\n"
++"SELECT foo FROM bar WHERE baz='${SQL_ESC(${ARG1})}'\n",
++ .read = acf_escape,
++ .write = NULL,
++};
++
++
++
++static int init_acf_query(struct ast_config *cfg, char *catg, struct acf_odbc_query **query)
++{
++ char *tmp;
++
++ if (!cfg || !catg) {
++ return -1;
++ }
++
++ *query = calloc(1, sizeof(struct acf_odbc_query));
++ if (! (*query))
++ return -1;
++
++ if ((tmp = ast_variable_retrieve(cfg, catg, "dsn"))) {
++ ast_copy_string((*query)->dsn, tmp, sizeof((*query)->dsn));
++ } else {
++ return -1;
++ }
++
++ if ((tmp = ast_variable_retrieve(cfg, catg, "read"))) {
++ ast_copy_string((*query)->sql_read, tmp, sizeof((*query)->sql_read));
++ }
++
++ if ((tmp = ast_variable_retrieve(cfg, catg, "write"))) {
++ ast_copy_string((*query)->sql_write, tmp, sizeof((*query)->sql_write));
++ }
++
++ (*query)->acf = calloc(1, sizeof(struct ast_custom_function));
++ if (! (*query)->acf) {
++ free(*query);
++ return -1;
++ }
++
++ if ((tmp = ast_variable_retrieve(cfg, catg, "prefix")) && !ast_strlen_zero(tmp)) {
++ asprintf((char **)&((*query)->acf->name), "%s_%s", tmp, catg);
++ } else {
++ asprintf((char **)&((*query)->acf->name), "ODBC_%s", catg);
++ }
++
++ if (!((*query)->acf->name)) {
++ free((*query)->acf);
++ free(*query);
++ return -1;
++ }
++
++ asprintf((char **)&((*query)->acf->syntax), "%s(<arg1>[...[,<argN>]])", (*query)->acf->name);
++
++ if (!((*query)->acf->syntax)) {
++ free((char *)(*query)->acf->name);
++ free((*query)->acf);
++ free(*query);
++ return -1;
++ }
++
++ (*query)->acf->synopsis = "Runs the referenced query with the specified arguments";
++ if (!ast_strlen_zero((*query)->sql_read) && !ast_strlen_zero((*query)->sql_write)) {
++ asprintf((char **)&((*query)->acf->desc),
++ "Runs the following query, as defined in func_odbc.conf, performing\n"
++ "substitution of the arguments into the query as specified by ${ARG1},\n"
++ "${ARG2}, ... ${ARGn}. When setting the function, the values are provided\n"
++ "either in whole as ${VALUE} or parsed as ${VAL1}, ${VAL2}, ... ${VALn}.\n"
++ "\nRead:\n%s\n\nWrite:\n%s\n",
++ (*query)->sql_read,
++ (*query)->sql_write);
++ } else if (!ast_strlen_zero((*query)->sql_read)) {
++ asprintf((char **)&((*query)->acf->desc),
++ "Runs the following query, as defined in func_odbc.conf, performing\n"
++ "substitution of the arguments into the query as specified by ${ARG1},\n"
++ "${ARG2}, ... ${ARGn}. This function may only be read, not set.\n\nSQL:\n%s\n",
++ (*query)->sql_read);
++ } else if (!ast_strlen_zero((*query)->sql_write)) {
++ asprintf((char **)&((*query)->acf->desc),
++ "Runs the following query, as defined in func_odbc.conf, performing\n"
++ "substitution of the arguments into the query as specified by ${ARG1},\n"
++ "${ARG2}, ... ${ARGn}. The values are provided either in whole as\n"
++ "${VALUE} or parsed as ${VAL1}, ${VAL2}, ... ${VALn}.\n"
++ "This function may only be set.\nSQL:\n%s\n",
++ (*query)->sql_write);
++ }
++
++ /* Could be out of memory, or could be we have neither sql_read nor sql_write */
++ if (! ((*query)->acf->desc)) {
++ free((char *)(*query)->acf->syntax);
++ free((char *)(*query)->acf->name);
++ free((*query)->acf);
++ free(*query);
++ return -1;
++ }
++
++ if (ast_strlen_zero((*query)->sql_read)) {
++ (*query)->acf->read = NULL;
++ } else {
++ (*query)->acf->read = acf_odbc_read;
++ }
++
++ if (ast_strlen_zero((*query)->sql_write)) {
++ (*query)->acf->write = NULL;
++ } else {
++ (*query)->acf->write = acf_odbc_write;
++ }
++
++ return 0;
++}
++
++static int free_acf_query(struct acf_odbc_query *query)
++{
++ if (query) {
++ if (query->acf) {
++ if (query->acf->name)
++ free(query->acf->name);
++ if (query->acf->syntax)
++ free(query->acf->syntax);
++ if (query->acf->desc)
++ free(query->acf->desc);
++ free(query->acf);
++ }
++ free(query);
++ }
++ return 0;
++}
++
++static int odbc_load_module(void)
++{
++ int res = 0;
++ struct ast_config *cfg;
++ char *catg;
++
++ AST_LIST_LOCK(&queries);
++
++ cfg = ast_config_load(config);
++ if (!cfg) {
++ ast_log(LOG_WARNING, "Unable to load config for func_odbc: %s\n", config);
++ AST_LIST_UNLOCK(&queries);
++ return -1;
++ }
++
++ for (catg = ast_category_browse(cfg, NULL);
++ catg;
++ catg = ast_category_browse(cfg, catg)) {
++ struct acf_odbc_query *query = NULL;
++
++ if (init_acf_query(cfg, catg, &query)) {
++ ast_log(LOG_ERROR, "Out of memory\n");
++ free_acf_query(query);
++ } else {
++ AST_LIST_INSERT_HEAD(&queries, query, list);
++ ast_custom_function_register(query->acf);
++ }
++ }
++
++ ast_config_destroy(cfg);
++ ast_custom_function_register(&escape_function);
++
++ AST_LIST_UNLOCK(&queries);
++ return res;
++}
++
++static int odbc_unload_module(void)
++{
++ struct acf_odbc_query *query;
++
++ AST_LIST_LOCK(&queries);
++ while (!AST_LIST_EMPTY(&queries)) {
++ query = AST_LIST_REMOVE_HEAD(&queries, list);
++ ast_custom_function_unregister(query->acf);
++ free_acf_query(query);
++ }
++
++ ast_custom_function_unregister(&escape_function);
++
++ /* Allow any threads waiting for this lock to pass (avoids a race) */
++ AST_LIST_UNLOCK(&queries);
++ AST_LIST_LOCK(&queries);
++
++ AST_LIST_UNLOCK(&queries);
++ return 0;
++}
++
++int reload(void)
++{
++ int res = 0;
++ struct ast_config *cfg;
++ struct acf_odbc_query *oldquery;
++ char *catg;
++
++ AST_LIST_LOCK(&queries);
++
++ while (!AST_LIST_EMPTY(&queries)) {
++ oldquery = AST_LIST_REMOVE_HEAD(&queries, list);
++ ast_custom_function_unregister(oldquery->acf);
++ free_acf_query(oldquery);
++ }
++
++ cfg = ast_config_load(config);
++ if (!cfg) {
++ ast_log(LOG_WARNING, "Unable to load config for func_odbc: %s\n", config);
++ goto reload_out;
++ }
++
++ for (catg = ast_category_browse(cfg, NULL);
++ catg;
++ catg = ast_category_browse(cfg, catg)) {
++ struct acf_odbc_query *query = NULL;
++
++ if (init_acf_query(cfg, catg, &query)) {
++ ast_log(LOG_ERROR, "Cannot initialize query %s\n", catg);
++ } else {
++ AST_LIST_INSERT_HEAD(&queries, query, list);
++ ast_custom_function_register(query->acf);
++ }
++ }
++
++ ast_config_destroy(cfg);
++reload_out:
++ AST_LIST_UNLOCK(&queries);
++ return res;
++}
++
++int unload_module(void)
++{
++ return odbc_unload_module();
++}
++
++int load_module(void)
++{
++ return odbc_load_module();
++}
++
++char *description(void)
++{
++ return tdesc;
++}
++
++int usecount(void)
++{
++ if (! ast_mutex_trylock(&(&queries)->lock)) {
++ ast_mutex_unlock(&(&queries)->lock);
++ return 0;
++ } else {
++ return 1;
++ }
++}
++
++char *key()
++{
++ return ASTERISK_GPL_KEY;
++}
Property changes on: asterisk/branches/sarge/debian/patches/func_odbc_12.dpatch
___________________________________________________________________
Name: svn:executable
+ *
Modified: asterisk/branches/sarge/debian/patches/option_detach.dpatch
===================================================================
--- asterisk/branches/sarge/debian/patches/option_detach.dpatch 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/patches/option_detach.dpatch 2006-05-16 10:42:26 UTC (rev 1767)
@@ -2,7 +2,7 @@
## option_detach.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
##
## All lines beginning with `## DP:' are a description of the patch.
-## DP: when running asterisk -D: detach, even if -v or -d was given
+## DP: when running asterisk -F: detach, even if -v or -d was given
## -- applied upstream as -F option to *force* forking
## -- in trunk (will be 1.4.x)
@@ -14,7 +14,7 @@
int option_nofork=0; /*!< Do not fork */
int option_quiet=0; /*!< Keep quiet */
int option_console=0; /*!< Console mode, no background */
-+int option_daemonize=0; /*!< Daemonize. Ever if -v or -d */
++int option_daemonize=0; /*!< Daemonize. Ever if -v or -d */
int option_highpriority=0; /*!< Run in realtime Linux priority */
int option_remote=0; /*!< Remote CLI */
int option_exec=0; /*!< */
@@ -22,7 +22,7 @@
printf(" -G <group> Run as a group other than the caller\n");
printf(" -U <user> Run as a user other than the caller\n");
printf(" -c Provide console CLI\n");
-+ printf(" -D Daemonize even if -v or -d were given\n");
++ printf(" -F Force Fork even if -v or -d were given\n");
printf(" -d Enable extra debugging\n");
printf(" -f Do not fork\n");
printf(" -g Dump core in case of a crash\n");
@@ -31,7 +31,7 @@
*/
/* Check for options */
- while((c=getopt(argc, argv, "tThfdvVqprRgcinx:U:G:C:L:M:")) != -1) {
-+ while((c=getopt(argc, argv, "tThfdvVqprRgcDinx:U:G:C:L:M:")) != -1) {
++ while((c=getopt(argc, argv, "tThfdvVqprRgcFinx:U:G:C:L:M:")) != -1) {
switch(c) {
case 'd':
option_debug++;
@@ -39,7 +39,7 @@
option_console++;
option_nofork++;
break;
-+ case 'D':
++ case 'F':
+ option_daemonize++;
+ break;
case 'f':
Added: asterisk/branches/sarge/debian/patches/sys_editline.dpatch
===================================================================
--- asterisk/branches/sarge/debian/patches/sys_editline.dpatch 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/patches/sys_editline.dpatch 2006-05-16 10:42:26 UTC (rev 1767)
@@ -0,0 +1,29 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## sys_readline.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Use the system copy of editline
+
+ at DPATCH@
+diff -urNad asterisk-1.2.7.1.dfsg/Makefile /tmp/dpep.nfcwXR/asterisk-1.2.7.1.dfsg/Makefile
+--- asterisk-1.2.7.1.dfsg/Makefile 2006-04-12 00:58:47.000000000 +0300
++++ /tmp/dpep.nfcwXR/asterisk-1.2.7.1.dfsg/Makefile 2006-05-13 22:54:43.051344312 +0300
+@@ -305,7 +305,8 @@
+
+ endif # WITHOUT_ZAPTEL
+
+-LIBEDIT=editline/libedit.a
++#LIBEDIT=editline/libedit.a
++LIBS+=-ledit
+
+ ifneq ($(wildcard .version),)
+ ASTERISKVERSION:=$(shell cat .version)
+@@ -513,7 +514,7 @@
+ cygwin_a:
+ $(MAKE) -C cygwin all
+
+-asterisk: $(CYGLOADER) editline/libedit.a db1-ast/libdb1.a stdtime/libtime.a $(OBJS)
++asterisk: $(CYGLOADER) db1-ast/libdb1.a stdtime/libtime.a $(OBJS)
+ build_tools/make_build_h > include/asterisk/build.h.tmp
+ if cmp -s include/asterisk/build.h.tmp include/asterisk/build.h ; then echo ; else \
+ mv include/asterisk/build.h.tmp include/asterisk/build.h ; \
Property changes on: asterisk/branches/sarge/debian/patches/sys_editline.dpatch
___________________________________________________________________
Name: svn:executable
+ *
Added: asterisk/branches/sarge/debian/patches/sys_readline.dpatch
===================================================================
--- asterisk/branches/sarge/debian/patches/sys_readline.dpatch 2006-05-15 17:35:50 UTC (rev 1766)
+++ asterisk/branches/sarge/debian/patches/sys_readline.dpatch 2006-05-16 10:42:26 UTC (rev 1767)
@@ -0,0 +1,356 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## sys_readline.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Use readline for the CLI. partially works.
+
+ at DPATCH@
+diff -urNad asterisk-1.2.7.1.dfsg/asterisk.c /tmp/dpep.yLtN9f/asterisk-1.2.7.1.dfsg/asterisk.c
+--- asterisk-1.2.7.1.dfsg/asterisk.c 2006-05-16 10:34:54.818659487 +0300
++++ /tmp/dpep.yLtN9f/asterisk-1.2.7.1.dfsg/asterisk.c 2006-05-16 10:37:29.595033197 +0300
+@@ -114,7 +114,12 @@
+ #include "asterisk/file.h"
+ #include "asterisk/io.h"
+ #include "asterisk/lock.h"
++#ifdef SYS_READLINE
++#include <readline/readline.h>
++#include <readline/history.h>
++#else /* SYS_READLINE */
+ #include "editline/histedit.h"
++#endif /* SYS_READLINE */
+ #include "asterisk/config.h"
+ #include "asterisk/version.h"
+ #include "asterisk/linkedlists.h"
+@@ -198,8 +203,12 @@
+ time_t ast_startuptime;
+ time_t ast_lastreloadtime;
+
++#ifdef SYS_READLINE
++static const char * rl_readline_name = "asterisk";
++#else
+ static History *el_hist = NULL;
+ static EditLine *el = NULL;
++#endif /* SYS_READLINE */
+ static char *remotehostname;
+
+ struct console consoles[AST_MAX_CONNECTS];
+@@ -717,6 +726,15 @@
+ ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
+ return 0;
+ }
++#ifdef SYS_READLINE
++ /* If we use readline, we'll use its main loop, and non-blocking
++ * reads */
++ if (0 != fcntl(ast_consock, F_SETFL, O_NONBLOCK)) {
++ ast_log(LOG_WARNING, "Unable to set socket non-blocking: %s\n",
++ strerror(errno));
++ return 0;
++ }
++#endif
+ memset(&sunaddr, 0, sizeof(sunaddr));
+ sunaddr.sun_family = AF_LOCAL;
+ ast_copy_string(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
+@@ -889,11 +907,15 @@
+ if (getenv("HOME"))
+ snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
+ if (!ast_strlen_zero(filename))
++#ifdef SYS_READLINE
++ write_history(filename);
++#else /* SYS_READLINE */
+ ast_el_write_history(filename);
+ if (el != NULL)
+ el_end(el);
+ if (el_hist != NULL)
+ history_end(el_hist);
++#endif /* SYS_READLINE */
+ }
+ if (option_verbose)
+ ast_verbose("Executing last minute cleanups\n");
+@@ -1001,7 +1023,11 @@
+ fflush(stdout);
+ /* Called when readline data is available */
+ if (s && !ast_all_zeros(s))
++#ifdef SYS_READLINE
++ add_history(s);
++#else /* SYS_READLINE */
+ ast_el_add_history(s);
++#endif /* SYS_READLINE */
+ /* Give the console access to the shell */
+ if (s) {
+ /* The real handler for bang */
+@@ -1021,7 +1047,11 @@
+ int ret = 0;
+ /* Called when readline data is available */
+ if (s && !ast_all_zeros(s))
++#ifdef SYS_READLINE
++ add_history(s);
++#else /* SYS_READLINE */
+ ast_el_add_history(s);
++#endif /* SYS_READLINE */
+ /* Give the console access to the shell */
+ if (s) {
+ /* The real handler for bang */
+@@ -1253,7 +1283,76 @@
+ #endif /* ! LOW_MEMORY */
+ };
+
++
++static void attempt_reconnect(void)
++{
++ int tries;
++ int reconnects_per_second = 20;
++ fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
++ for (tries=0;tries<30 * reconnects_per_second;tries++) {
++ if (ast_tryconnect()) {
++ fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
++ printf(term_quit());
++ WELCOME_MESSAGE;
++ break;
++ } else {
++ usleep(1000000 / reconnects_per_second);
++ }
++ }
++ if (tries >= 30 * reconnects_per_second) {
++ fprintf(stderr, "Failed to reconnect for 30 seconds. Quitting.\n");
++ quit_handler(0, 0, 0, 0);
++ }
++}
++
++/* Called by readline every 0.1 seconds or so from its main loop. */
++static int ast_rl_event_hook(void)
++{
++#ifdef SYS_READLINE
++ int res;
++ char buf[512];
++
++ res = read(ast_consock, buf, sizeof(buf) - 1);
++ /* if the remote side disappears exit */
++ if ((res == -1) && (errno == EAGAIN))
++ return 0; /* There was nothing to read. Maybe next time. */
++
++ if (res < 1) {
++ fprintf(stderr, "\nDisconnected from Asterisk server: %s.\n",
++ strerror(errno));
++ if (!option_reconnect) {
++ quit_handler(0, 0, 0, 0);
++ } else {
++ attempt_reconnect();
++ }
++ /* never reached */
++ }
++
++ buf[res] = '\0';
++
++ /* Let's assume we always get complete lines in read-s */
++ fputc('\r', rl_outstream); /* to beginning of line... */
++ /* suppress an excessive linefeed: */
++ if (buf[res-1] == '\n') {
++ buf[res-1] = '\0';
++ }
++ fputs(buf, rl_outstream); /* The text itself */
++ if (option_exec)
++ return 0;
++ /* and refresh readline's prompt */
++ rl_forced_update_display();
++
++ return 0;
++#endif
++}
++
++#ifdef SYS_READLINE
++/* TODO: this #define means we're doing something wrong. */
++#define CC_REFRESH 4
++static int ast_rl_read_char(char *cp)
++#else
+ static int ast_el_read_char(EditLine *el, char *cp)
++#endif
+ {
+ int num_read=0;
+ int lastpos=0;
+@@ -1332,13 +1431,15 @@
+ return (0);
+ }
+
+-static char *cli_prompt(EditLine *el)
++static char *cli_prompt(void)
+ {
+ static char prompt[200];
+ char *pfmt;
+ int color_used=0;
+ char term_code[20];
+
++ if (option_exec)
++ return "";
+ if ((pfmt = getenv("ASTERISK_PROMPT"))) {
+ char *t = pfmt, *p = prompt;
+ memset(prompt, 0, sizeof(prompt));
+@@ -1477,6 +1578,7 @@
+ return(prompt);
+ }
+
++#ifndef SYS_READLINE
+ static char **ast_el_strtoarr(char *buf)
+ {
+ char **match_list = NULL, *retstr;
+@@ -1754,6 +1856,20 @@
+
+ return ret;
+ }
++#endif /* SYS_READLINE */
++
++static void ast_rl_initialize(void)
++{
++ static int initilized = 0;
++ /* ignore races for the moment */
++ if (!initilized) {
++ rl_initialize();
++ rl_set_prompt(cli_prompt());
++ rl_event_hook = ast_rl_event_hook;
++ //fprintf(stderr, "===INITILIZING READLINE==[%s]====\n", cli_prompt());
++ initilized = 1;
++ }
++}
+
+ static void ast_remotecontrol(char * data)
+ {
+@@ -1768,7 +1884,7 @@
+ char *stringp=NULL;
+
+ char *ebuf;
+- int num = 0;
++ //int num = 0;
+
+ read(ast_consock, buf, sizeof(buf));
+ if (data)
+@@ -1793,6 +1909,9 @@
+ remotehostname = hostname;
+ if (getenv("HOME"))
+ snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
++#ifdef SYS_READLINE
++ ast_rl_initialize();
++#else /* SYS_READLINE */
+ if (el_hist == NULL || el == NULL)
+ ast_el_initialize();
+
+@@ -1800,7 +1919,8 @@
+
+ if (!ast_strlen_zero(filename))
+ ast_el_read_history(filename);
+-
++#endif /* SYS_READLINE */
++
+ if (option_exec && data) { /* hack to print output then exit if asterisk -rx is used */
+ char tempchar;
+ struct pollfd fds[0];
+@@ -1808,12 +1928,21 @@
+ fds[0].events = POLLIN;
+ fds[0].revents = 0;
+ while(poll(fds, 1, 100) > 0) {
++#ifdef SYS_READLINE
++ //ast_rl_read_char(&tempchar);
++ ast_rl_event_hook();
++#else
+ ast_el_read_char(el, &tempchar);
++#endif
+ }
+ return;
+ }
+ for(;;) {
++#ifdef SYS_READLINE
++ ebuf = readline(cli_prompt());
++#else
+ ebuf = (char *)el_gets(el, &num);
++#endif
+
+ if (!ast_strlen_zero(ebuf)) {
+ if (ebuf[strlen(ebuf)-1] == '\n')
+@@ -2023,7 +2152,7 @@
+ int x;
+ FILE *f;
+ sigset_t sigs;
+- int num;
++ //int num;
+ int is_child_of_nonroot=0;
+ char *buf;
+ char *runuser=NULL, *rungroup=NULL;
+@@ -2221,6 +2350,10 @@
+ ast_log(LOG_WARNING, "Unable to initialize supplementary group list for %s\n", runuser);
+ exit(1);
+ }
++ if (!rungroup && initgroups(runuser, pw->pw_gid)) {
++ ast_log(LOG_WARNING, "Unable to initialize supplementary group list for %s\n", runuser);
++ exit(1);
++ }
+ if (setuid(pw->pw_uid)) {
+ ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
+ exit(1);
+@@ -2254,11 +2387,15 @@
+
+
+ if (option_console) {
++#ifdef SYS_READLINE
++ ast_rl_initialize();
++#else
+ if (el_hist == NULL || el == NULL)
+ ast_el_initialize();
+
+ if (!ast_strlen_zero(filename))
+ ast_el_read_history(filename);
++#endif /* SYS_READLINE */
+ }
+
+ if (ast_tryconnect()) {
+@@ -2435,7 +2573,8 @@
+ set_title(title);
+
+ for (;;) {
+- buf = (char *)el_gets(el, &num);
++ //buf = (char *)el_gets(el, &num);
++ buf = readline(cli_prompt());
+ if (buf) {
+ if (buf[strlen(buf)-1] == '\n')
+ buf[strlen(buf)-1] = '\0';
+diff -urNad asterisk-1.2.7.1.dfsg/cli.c /tmp/dpep.yLtN9f/asterisk-1.2.7.1.dfsg/cli.c
+--- asterisk-1.2.7.1.dfsg/cli.c 2006-05-16 10:34:54.045457773 +0300
++++ /tmp/dpep.yLtN9f/asterisk-1.2.7.1.dfsg/cli.c 2006-05-16 10:34:55.592861462 +0300
+@@ -44,7 +44,15 @@
+ #include "asterisk/utils.h"
+ #include "asterisk/lock.h"
+ /* For rl_filename_completion */
++#ifndef SYS_READLINE
+ #include "editline/readline/readline.h"
++#else
++# ifdef SYS_READLINE_EDIT
++# include <editline/readline.h>
++# else
++# include <readline/readline.h>
++# endif
++#endif
+ /* For module directory */
+ #include "asterisk/version.h"
+
+diff -urNad asterisk-1.2.7.1.dfsg/Makefile /tmp/dpep.yLtN9f/asterisk-1.2.7.1.dfsg/Makefile
+--- asterisk-1.2.7.1.dfsg/Makefile 2006-05-16 10:34:54.818659487 +0300
++++ /tmp/dpep.yLtN9f/asterisk-1.2.7.1.dfsg/Makefile 2006-05-16 10:34:55.850928786 +0300
+@@ -307,7 +307,11 @@
+
+ endif # WITHOUT_ZAPTEL
+
+-LIBEDIT=editline/libedit.a
++#LIBEDIT=editline/libedit.a
++#LIBS+=-ledit
++LIBS+=-lreadline
++ASTCFLAGS+=-DSYS_READLINE
++#ASTCFLAGS+=-DSYS_READLINE_EDIT
+
+ ifneq ($(wildcard .version),)
+ ASTERISKVERSION:=$(shell cat .version)
+@@ -515,7 +519,7 @@
+ cygwin_a:
+ $(MAKE) -C cygwin all
+
+-asterisk: $(CYGLOADER) editline/libedit.a db1-ast/libdb1.a stdtime/libtime.a $(OBJS)
++asterisk: $(CYGLOADER) db1-ast/libdb1.a stdtime/libtime.a $(OBJS)
+ build_tools/make_build_h > include/asterisk/build.h.tmp
+ if cmp -s include/asterisk/build.h.tmp include/asterisk/build.h ; then echo ; else \
+ mv include/asterisk/build.h.tmp include/asterisk/build.h ; \
Property changes on: asterisk/branches/sarge/debian/patches/sys_readline.dpatch
___________________________________________________________________
Name: svn:executable
+ *
More information about the Pkg-voip-commits
mailing list