[asterisk-commits] oej: branch oej/oolong-path-support-1.8 r375355 - in /team/oej/oolong-path-su...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Oct 28 05:34:14 CDT 2012


Author: oej
Date: Sun Oct 28 05:34:00 2012
New Revision: 375355

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=375355
Log:
Updating to latest 1.8

Modified:
    team/oej/oolong-path-support-1.8/   (props changed)
    team/oej/oolong-path-support-1.8/CHANGES
    team/oej/oolong-path-support-1.8/Makefile
    team/oej/oolong-path-support-1.8/UPGRADE.txt
    team/oej/oolong-path-support-1.8/apps/app_dial.c
    team/oej/oolong-path-support-1.8/apps/app_followme.c
    team/oej/oolong-path-support-1.8/apps/app_meetme.c
    team/oej/oolong-path-support-1.8/apps/app_minivm.c
    team/oej/oolong-path-support-1.8/apps/app_mixmonitor.c
    team/oej/oolong-path-support-1.8/apps/app_queue.c
    team/oej/oolong-path-support-1.8/apps/app_senddtmf.c
    team/oej/oolong-path-support-1.8/apps/app_voicemail.c
    team/oej/oolong-path-support-1.8/build_tools/make_version
    team/oej/oolong-path-support-1.8/cel/cel_pgsql.c
    team/oej/oolong-path-support-1.8/channels/chan_agent.c
    team/oej/oolong-path-support-1.8/channels/chan_iax2.c
    team/oej/oolong-path-support-1.8/channels/chan_local.c
    team/oej/oolong-path-support-1.8/channels/chan_misdn.c
    team/oej/oolong-path-support-1.8/channels/chan_sip.c
    team/oej/oolong-path-support-1.8/channels/iax2-provision.c
    team/oej/oolong-path-support-1.8/channels/misdn/isdn_lib.c
    team/oej/oolong-path-support-1.8/channels/misdn/isdn_lib.h
    team/oej/oolong-path-support-1.8/channels/misdn/isdn_msg_parser.c
    team/oej/oolong-path-support-1.8/channels/sig_ss7.c
    team/oej/oolong-path-support-1.8/channels/sip/include/sip.h
    team/oej/oolong-path-support-1.8/channels/sip/sdp_crypto.c
    team/oej/oolong-path-support-1.8/codecs/Makefile
    team/oej/oolong-path-support-1.8/codecs/gsm/src/code.c
    team/oej/oolong-path-support-1.8/codecs/ilbc/iLBC_decode.c
    team/oej/oolong-path-support-1.8/codecs/ilbc/iLBC_encode.c
    team/oej/oolong-path-support-1.8/config.guess
    team/oej/oolong-path-support-1.8/config.sub
    team/oej/oolong-path-support-1.8/configs/agents.conf.sample
    team/oej/oolong-path-support-1.8/configs/chan_dahdi.conf.sample
    team/oej/oolong-path-support-1.8/configs/dsp.conf.sample
    team/oej/oolong-path-support-1.8/configs/res_ldap.conf.sample
    team/oej/oolong-path-support-1.8/configs/res_odbc.conf.sample
    team/oej/oolong-path-support-1.8/configs/sip.conf.sample
    team/oej/oolong-path-support-1.8/configure
    team/oej/oolong-path-support-1.8/configure.ac
    team/oej/oolong-path-support-1.8/contrib/scripts/ast_tls_cert
    team/oej/oolong-path-support-1.8/contrib/scripts/autosupport
    team/oej/oolong-path-support-1.8/funcs/func_audiohookinherit.c
    team/oej/oolong-path-support-1.8/funcs/func_math.c
    team/oej/oolong-path-support-1.8/include/asterisk/astdb.h
    team/oej/oolong-path-support-1.8/include/asterisk/astobj2.h
    team/oej/oolong-path-support-1.8/include/asterisk/channel.h
    team/oej/oolong-path-support-1.8/include/asterisk/strings.h
    team/oej/oolong-path-support-1.8/include/asterisk/tcptls.h
    team/oej/oolong-path-support-1.8/main/Makefile
    team/oej/oolong-path-support-1.8/main/app.c
    team/oej/oolong-path-support-1.8/main/asterisk.c
    team/oej/oolong-path-support-1.8/main/astmm.c
    team/oej/oolong-path-support-1.8/main/astobj2.c
    team/oej/oolong-path-support-1.8/main/ccss.c
    team/oej/oolong-path-support-1.8/main/cdr.c
    team/oej/oolong-path-support-1.8/main/cel.c
    team/oej/oolong-path-support-1.8/main/channel.c
    team/oej/oolong-path-support-1.8/main/data.c
    team/oej/oolong-path-support-1.8/main/db.c
    team/oej/oolong-path-support-1.8/main/dsp.c
    team/oej/oolong-path-support-1.8/main/event.c
    team/oej/oolong-path-support-1.8/main/features.c
    team/oej/oolong-path-support-1.8/main/indications.c
    team/oej/oolong-path-support-1.8/main/loader.c
    team/oej/oolong-path-support-1.8/main/manager.c
    team/oej/oolong-path-support-1.8/main/pbx.c
    team/oej/oolong-path-support-1.8/main/say.c
    team/oej/oolong-path-support-1.8/main/ssl.c
    team/oej/oolong-path-support-1.8/main/taskprocessor.c
    team/oej/oolong-path-support-1.8/main/tcptls.c
    team/oej/oolong-path-support-1.8/makeopts.in
    team/oej/oolong-path-support-1.8/pbx/pbx_dundi.c
    team/oej/oolong-path-support-1.8/pbx/pbx_spool.c
    team/oej/oolong-path-support-1.8/res/res_agi.c
    team/oej/oolong-path-support-1.8/res/res_jabber.c
    team/oej/oolong-path-support-1.8/res/res_musiconhold.c
    team/oej/oolong-path-support-1.8/res/res_rtp_asterisk.c
    team/oej/oolong-path-support-1.8/res/res_rtp_multicast.c
    team/oej/oolong-path-support-1.8/tests/test_db.c

Propchange: team/oej/oolong-path-support-1.8/
------------------------------------------------------------------------------
    automerge = Is-there-life-off-net?

Propchange: team/oej/oolong-path-support-1.8/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sun Oct 28 05:34:00 2012
@@ -1,1 +1,1 @@
-/branches/1.8:1-372126
+/branches/1.8:1-375354

Modified: team/oej/oolong-path-support-1.8/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/oej/oolong-path-support-1.8/CHANGES?view=diff&rev=375355&r1=375354&r2=375355
==============================================================================
--- team/oej/oolong-path-support-1.8/CHANGES (original)
+++ team/oej/oolong-path-support-1.8/CHANGES Sun Oct 28 05:34:00 2012
@@ -633,6 +633,9 @@
    rate changes during translation are now avoided unless absolutely necessary.
  * The addition of the res_stun_monitor module for monitoring and reacting to network
    changes while behind a NAT.
+ * DTMF: Normal and Reverse Twist acceptance values can be set in dsp.conf.
+   DTMF Valid/Invalid number of hits/misses can be set in dsp.conf.
+   These allow support for any Administration. Default is AT&T values.
 
 CLI Changes
 -----------

Modified: team/oej/oolong-path-support-1.8/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/oej/oolong-path-support-1.8/Makefile?view=diff&rev=375355&r1=375354&r2=375355
==============================================================================
--- team/oej/oolong-path-support-1.8/Makefile (original)
+++ team/oej/oolong-path-support-1.8/Makefile Sun Oct 28 05:34:00 2012
@@ -204,7 +204,7 @@
   _ASTCFLAGS+=-Wcast-align -DSOLARIS -I../include/solaris-compat -I/opt/ssl/include -I/usr/local/ssl/include -D_XPG4_2 -D__EXTENSIONS__
 endif
 
-ASTERISKVERSION:=$(shell GREP=$(GREP) AWK=$(AWK) build_tools/make_version .)
+ASTERISKVERSION:=$(shell GREP=$(GREP) AWK=$(AWK) GIT=$(GIT) build_tools/make_version .)
 
 ifneq ($(wildcard .version),)
   ASTERISKVERSIONNUM:=$(shell $(AWK) -F. '{printf "%01d%02d%02d", $$1, $$2, $$3}' .version)

Modified: team/oej/oolong-path-support-1.8/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/oej/oolong-path-support-1.8/UPGRADE.txt?view=diff&rev=375355&r1=375354&r2=375355
==============================================================================
--- team/oej/oolong-path-support-1.8/UPGRADE.txt (original)
+++ team/oej/oolong-path-support-1.8/UPGRADE.txt Sun Oct 28 05:34:00 2012
@@ -17,6 +17,15 @@
 === UPGRADE-1.6.txt -- Upgrade info for 1.4 to 1.6
 ===
 ===========================================================
+from 1.8.18 to 1.8.19:
+* Queue strategy rrmemory now has a predictable order similar to strategy
+  rrordered. Members will be called in the order that they are added to the
+  queue.
+
+From 1.8.13 to 1.8.14:
+* permitdirectmedia/denydirectmedia now controls whether peers can be
+  bridged via directmedia by comparing the ACL to the bridging peer's
+  address rather than its own address.
 
 From 1.8.12 to 1.8.13:
 * The complex processor detection and optimization has been removed from

Modified: team/oej/oolong-path-support-1.8/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/oolong-path-support-1.8/apps/app_dial.c?view=diff&rev=375355&r1=375354&r2=375355
==============================================================================
--- team/oej/oolong-path-support-1.8/apps/app_dial.c (original)
+++ team/oej/oolong-path-support-1.8/apps/app_dial.c Sun Oct 28 05:34:00 2012
@@ -672,7 +672,7 @@
 	struct ast_aoc_decoded *aoc_s_rate_list;
 };
 
-static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode);
+static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode);
 
 static void chanlist_free(struct chanlist *outgoing)
 {
@@ -1532,7 +1532,7 @@
 				}
 
 				if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
-					detect_disconnect(in, f->subclass.integer, featurecode)) {
+					detect_disconnect(in, f->subclass.integer, &featurecode)) {
 					ast_verb(3, "User requested call disconnect.\n");
 					*to = 0;
 					strcpy(pa->status, "CANCEL");
@@ -1645,18 +1645,18 @@
 	return peer;
 }
 
-static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode)
+static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode)
 {
 	struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
 	struct ast_call_feature feature = { 0, };
 	int res;
 
-	ast_str_append(&featurecode, 1, "%c", code);
-
-	res = ast_feature_detect(chan, &features, ast_str_buffer(featurecode), &feature);
+	ast_str_append(featurecode, 1, "%c", code);
+
+	res = ast_feature_detect(chan, &features, ast_str_buffer(*featurecode), &feature);
 
 	if (res != AST_FEATURE_RETURN_STOREDIGITS) {
-		ast_str_reset(featurecode);
+		ast_str_reset(*featurecode);
 	}
 	if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
 		return 1;

Modified: team/oej/oolong-path-support-1.8/apps/app_followme.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/oolong-path-support-1.8/apps/app_followme.c?view=diff&rev=375355&r1=375354&r2=375355
==============================================================================
--- team/oej/oolong-path-support-1.8/apps/app_followme.c (original)
+++ team/oej/oolong-path-support-1.8/apps/app_followme.c Sun Oct 28 05:34:00 2012
@@ -331,7 +331,7 @@
 	char *cat = NULL, *tmp;
 	struct ast_variable *var;
 	struct number *cur, *nm;
-	char numberstr[90];
+	char *numberstr;
 	int timeout;
 	int numorder;
 	const char *takecallstr;
@@ -447,7 +447,7 @@
 				int idx = 0;
 
 				/* Add a new number */
-				ast_copy_string(numberstr, var->value, sizeof(numberstr));
+				numberstr = ast_strdupa(var->value);
 				if ((tmp = strchr(numberstr, ','))) {
 					*tmp++ = '\0';
 					timeout = atoi(tmp);

Modified: team/oej/oolong-path-support-1.8/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/oolong-path-support-1.8/apps/app_meetme.c?view=diff&rev=375355&r1=375354&r2=375355
==============================================================================
--- team/oej/oolong-path-support-1.8/apps/app_meetme.c (original)
+++ team/oej/oolong-path-support-1.8/apps/app_meetme.c Sun Oct 28 05:34:00 2012
@@ -142,7 +142,8 @@
 					</option>
 					<option name="p" hasparams="optional">
 						<para>Allow user to exit the conference by pressing <literal>#</literal> (default)
-						or any of the defined keys.  The key used is set to channel variable
+						or any of the defined keys. Dial plan execution will continue at the next
+						priority following MeetMe. The key used is set to channel variable
 						<variable>MEETME_EXIT_KEY</variable>.</para>
 						<argument name="keys" required="true" />
 						<note>
@@ -512,8 +513,9 @@
 	</manager>
  ***/
 
-#define CONFIG_FILE_NAME "meetme.conf"
-#define SLA_CONFIG_FILE  "sla.conf"
+#define CONFIG_FILE_NAME	"meetme.conf"
+#define SLA_CONFIG_FILE		"sla.conf"
+#define STR_CONCISE			"concise"
 
 /*! each buffer is 20ms, so this is 640ms total */
 #define DEFAULT_AUDIO_BUFFERS  32
@@ -1296,71 +1298,131 @@
 	return cnf;
 }
 
-static char *complete_meetmecmd(const char *line, const char *word, int pos, int state)
-{
-	static const char * const cmds[] = {"concise", "lock", "unlock", "mute", "unmute", "kick", "list", NULL};
-
+static char *complete_confno(const char *word, int state)
+{
+	struct ast_conference *cnf;
+	char *ret = NULL;
+	int which = 0;
 	int len = strlen(word);
+
+	AST_LIST_LOCK(&confs);
+	AST_LIST_TRAVERSE(&confs, cnf, list) {
+		if (!strncmp(word, cnf->confno, len) && ++which > state) {
+			/* dup before releasing the lock */
+			ret = ast_strdup(cnf->confno);
+			break;
+		}
+	}
+	AST_LIST_UNLOCK(&confs);
+	return ret;
+}
+
+static char *complete_userno(struct ast_conference *cnf, const char *word, int state)
+{
+	char usrno[50];
+	struct ao2_iterator iter;
+	struct ast_conf_user *usr;
+	char *ret = NULL;
 	int which = 0;
-	struct ast_conference *cnf = NULL;
-	struct ast_conf_user *usr = NULL;
-	char *confno = NULL;
-	char usrno[50] = "";
-	char *myline, *ret = NULL;
-	
-	if (pos == 1) {		/* Command */
-		return ast_cli_complete(word, cmds, state);
-	} else if (pos == 2) {	/* Conference Number */
+	int len = strlen(word);
+
+	iter = ao2_iterator_init(cnf->usercontainer, 0);
+	for (; (usr = ao2_iterator_next(&iter)); ao2_ref(usr, -1)) {
+		snprintf(usrno, sizeof(usrno), "%d", usr->user_no);
+		if (!strncmp(word, usrno, len) && ++which > state) {
+			ao2_ref(usr, -1);
+			ret = ast_strdup(usrno);
+			break;
+		}
+	}
+	ao2_iterator_destroy(&iter);
+	return ret;
+}
+
+static char *complete_meetmecmd_mute_kick(const char *line, const char *word, int pos, int state)
+{
+	if (pos == 2) {
+		return complete_confno(word, state);
+	}
+	if (pos == 3) {
+		int len = strlen(word);
+		char *ret = NULL;
+		char *saved = NULL;
+		char *myline;
+		char *confno;
+		struct ast_conference *cnf;
+
+		if (!strncasecmp(word, "all", len)) {
+			if (state == 0) {
+				return ast_strdup("all");
+			}
+			--state;
+		}
+
+		/* Extract the confno from the command line. */
+		myline = ast_strdupa(line);
+		strtok_r(myline, " ", &saved);
+		strtok_r(NULL, " ", &saved);
+		confno = strtok_r(NULL, " ", &saved);
+
 		AST_LIST_LOCK(&confs);
 		AST_LIST_TRAVERSE(&confs, cnf, list) {
-			if (!strncasecmp(word, cnf->confno, len) && ++which > state) {
-				ret = cnf->confno;
+			if (!strcmp(confno, cnf->confno)) {
+				ret = complete_userno(cnf, word, state);
 				break;
 			}
 		}
-		ret = ast_strdup(ret); /* dup before releasing the lock */
 		AST_LIST_UNLOCK(&confs);
+
 		return ret;
-	} else if (pos == 3) {
-		/* User Number || Conf Command option*/
-		if (strstr(line, "mute") || strstr(line, "kick")) {
-			if (state == 0 && (strstr(line, "kick") || strstr(line, "mute")) && !strncasecmp(word, "all", len))
-				return ast_strdup("all");
-			which++;
-			AST_LIST_LOCK(&confs);
-
-			/* TODO: Find the conf number from the cmdline (ignore spaces) <- test this and make it fail-safe! */
-			myline = ast_strdupa(line);
-			if (strsep(&myline, " ") && strsep(&myline, " ") && !confno) {
-				while((confno = strsep(&myline, " ")) && (strcmp(confno, " ") == 0))
-					;
+	}
+	return NULL;
+}
+
+static char *complete_meetmecmd_lock(const char *word, int pos, int state)
+{
+	if (pos == 2) {
+		return complete_confno(word, state);
+	}
+	return NULL;
+}
+
+static char *complete_meetmecmd_list(const char *line, const char *word, int pos, int state)
+{
+	int len;
+
+	if (pos == 2) {
+		len = strlen(word);
+		if (!strncasecmp(word, STR_CONCISE, len)) {
+			if (state == 0) {
+				return ast_strdup(STR_CONCISE);
 			}
-			
-			AST_LIST_TRAVERSE(&confs, cnf, list) {
-				if (!strcmp(confno, cnf->confno))
-				    break;
-			}
-
-			if (cnf) {
-				struct ao2_iterator user_iter;
-				user_iter = ao2_iterator_init(cnf->usercontainer, 0);
-
-				while((usr = ao2_iterator_next(&user_iter))) {
-					snprintf(usrno, sizeof(usrno), "%d", usr->user_no);
-					if (!strncasecmp(word, usrno, len) && ++which > state) {
-						ao2_ref(usr, -1);
-						break;
-					}
-					ao2_ref(usr, -1);
-				}
-				ao2_iterator_destroy(&user_iter);
-				AST_LIST_UNLOCK(&confs);
-				return usr ? ast_strdup(usrno) : NULL;
-			}
-			AST_LIST_UNLOCK(&confs);
-		}
-	}
-
+			--state;
+		}
+
+		return complete_confno(word, state);
+	}
+	if (pos == 3 && state == 0) {
+		char *saved = NULL;
+		char *myline;
+		char *confno;
+
+		/* Extract the confno from the command line. */
+		myline = ast_strdupa(line);
+		strtok_r(myline, " ", &saved);
+		strtok_r(NULL, " ", &saved);
+		confno = strtok_r(NULL, " ", &saved);
+
+		if (!strcasecmp(confno, STR_CONCISE)) {
+			/* There is nothing valid in this position now. */
+			return NULL;
+		}
+
+		len = strlen(word);
+		if (!strncasecmp(word, STR_CONCISE, len)) {
+			return ast_strdup(STR_CONCISE);
+		}
+	}
 	return NULL;
 }
 
@@ -1370,37 +1432,31 @@
 	struct ast_conf_user *user;
 	struct ast_conference *cnf;
 	int hr, min, sec;
-	int i = 0, total = 0;
+	int total = 0;
 	time_t now;
-	struct ast_str *cmdline = NULL;
 #define MC_HEADER_FORMAT "%-14s %-14s %-10s %-8s  %-8s  %-6s\n"
 #define MC_DATA_FORMAT "%-12.12s   %4.4d	      %4.4s       %02d:%02d:%02d  %-8s  %-6s\n"
 
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "meetme list [concise]";
+		e->command = "meetme list";
 		e->usage =
-			"Usage: meetme list [concise] <confno> \n"
-			"       List all or a specific conference.\n";
+			"Usage: meetme list [<confno>] [" STR_CONCISE "]\n"
+			"       List all conferences or a specific conference.\n";
 		return NULL;
 	case CLI_GENERATE:
-		return complete_meetmecmd(a->line, a->word, a->pos, a->n);
-	}
-
-	/* Check for length so no buffer will overflow... */
-	for (i = 0; i < a->argc; i++) {
-		if (strlen(a->argv[i]) > 100)
-			ast_cli(a->fd, "Invalid Arguments.\n");
-	}
-
-	/* Max confno length */
-	if (!(cmdline = ast_str_create(MAX_CONFNUM))) {
-		return CLI_FAILURE;
-	}
-
-	if (a->argc == 2 || (a->argc == 3 && !strcasecmp(a->argv[2], "concise"))) {
-		/* List all the conferences */	
-		int concise = (a->argc == 3 && !strcasecmp(a->argv[2], "concise"));
+		return complete_meetmecmd_list(a->line, a->word, a->pos, a->n);
+	}
+
+	if (a->argc == 2 || (a->argc == 3 && !strcasecmp(a->argv[2], STR_CONCISE))) {
+		/* List all the conferences */
+		int concise = (a->argc == 3);
+		struct ast_str *marked_users;
+
+		if (!(marked_users = ast_str_create(30))) {
+			return CLI_FAILURE;
+		}
+
 		now = time(NULL);
 		AST_LIST_LOCK(&confs);
 		if (AST_LIST_EMPTY(&confs)) {
@@ -1408,23 +1464,25 @@
 				ast_cli(a->fd, "No active MeetMe conferences.\n");
 			}
 			AST_LIST_UNLOCK(&confs);
-			ast_free(cmdline);
+			ast_free(marked_users);
 			return CLI_SUCCESS;
 		}
 		if (!concise) {
 			ast_cli(a->fd, MC_HEADER_FORMAT, "Conf Num", "Parties", "Marked", "Activity", "Creation", "Locked");
 		}
 		AST_LIST_TRAVERSE(&confs, cnf, list) {
-			if (cnf->markedusers == 0) {
-				ast_str_set(&cmdline, 0, "N/A ");
-			} else {
-				ast_str_set(&cmdline, 0, "%4.4d", cnf->markedusers);
-			}
 			hr = (now - cnf->start) / 3600;
 			min = ((now - cnf->start) % 3600) / 60;
 			sec = (now - cnf->start) % 60;
 			if (!concise) {
-				ast_cli(a->fd, MC_DATA_FORMAT, cnf->confno, cnf->users, ast_str_buffer(cmdline), hr, min, sec, cnf->isdynamic ? "Dynamic" : "Static", cnf->locked ? "Yes" : "No");
+				if (cnf->markedusers == 0) {
+					ast_str_set(&marked_users, 0, "N/A ");
+				} else {
+					ast_str_set(&marked_users, 0, "%4.4d", cnf->markedusers);
+				}
+				ast_cli(a->fd, MC_DATA_FORMAT, cnf->confno, cnf->users,
+					ast_str_buffer(marked_users), hr, min, sec,
+					cnf->isdynamic ? "Dynamic" : "Static", cnf->locked ? "Yes" : "No");
 			} else {
 				ast_cli(a->fd, "%s!%d!%d!%02d:%02d:%02d!%d!%d\n",
 					cnf->confno,
@@ -1441,18 +1499,19 @@
 		if (!concise) {
 			ast_cli(a->fd, "* Total number of MeetMe users: %d\n", total);
 		}
-		ast_free(cmdline);
+		ast_free(marked_users);
 		return CLI_SUCCESS;
-	} else if (strcmp(a->argv[1], "list") == 0) {
+	}
+	if (a->argc == 3 || (a->argc == 4 && !strcasecmp(a->argv[3], STR_CONCISE))) {
 		struct ao2_iterator user_iter;
-		int concise = (a->argc == 4 && (!strcasecmp(a->argv[3], "concise")));
+		int concise = (a->argc == 4);
+
 		/* List all the users in a conference */
 		if (AST_LIST_EMPTY(&confs)) {
 			if (!concise) {
 				ast_cli(a->fd, "No active MeetMe conferences.\n");
 			}
-			ast_free(cmdline);
-			return CLI_SUCCESS;	
+			return CLI_SUCCESS;
 		}
 		/* Find the right conference */
 		AST_LIST_LOCK(&confs);
@@ -1465,7 +1524,6 @@
 			if (!concise)
 				ast_cli(a->fd, "No such conference: %s.\n", a->argv[2]);
 			AST_LIST_UNLOCK(&confs);
-			ast_free(cmdline);
 			return CLI_SUCCESS;
 		}
 		/* Show all the users */
@@ -1505,93 +1563,49 @@
 			ast_cli(a->fd, "%d users in that conference.\n", cnf->users);
 		}
 		AST_LIST_UNLOCK(&confs);
-		ast_free(cmdline);
 		return CLI_SUCCESS;
 	}
-	if (a->argc < 2) {
-		ast_free(cmdline);
-		return CLI_SHOWUSAGE;
-	}
-
-	ast_debug(1, "Cmdline: %s\n", ast_str_buffer(cmdline));
-
-	admin_exec(NULL, ast_str_buffer(cmdline));
-	ast_free(cmdline);
-
-	return CLI_SUCCESS;
-}
-
-
-static char *meetme_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+	return CLI_SHOWUSAGE;
+}
+
+
+static char *meetme_cmd_helper(struct ast_cli_args *a)
 {
 	/* Process the command */
-	struct ast_str *cmdline = NULL;
-	int i = 0;
-
-	switch (cmd) {
-	case CLI_INIT:
-		e->command = "meetme {lock|unlock|mute|unmute|kick}";
-		e->usage =
-			"Usage: meetme (un)lock|(un)mute|kick <confno> <usernumber>\n"
-			"       Executes a command for the conference or on a conferee\n";
-		return NULL;
-	case CLI_GENERATE:
-		return complete_meetmecmd(a->line, a->word, a->pos, a->n);
-	}
-
-	if (a->argc > 8)
-		ast_cli(a->fd, "Invalid Arguments.\n");
-	/* Check for length so no buffer will overflow... */
-	for (i = 0; i < a->argc; i++) {
-		if (strlen(a->argv[i]) > 100)
-			ast_cli(a->fd, "Invalid Arguments.\n");
-	}
+	struct ast_str *cmdline;
 
 	/* Max confno length */
 	if (!(cmdline = ast_str_create(MAX_CONFNUM))) {
 		return CLI_FAILURE;
 	}
 
-	if (a->argc < 1) {
-		ast_free(cmdline);
-		return CLI_SHOWUSAGE;
-	}
-
 	ast_str_set(&cmdline, 0, "%s", a->argv[2]);	/* Argv 2: conference number */
-	if (strstr(a->argv[1], "lock")) {
-		if (strcmp(a->argv[1], "lock") == 0) {
+	if (strcasestr(a->argv[1], "lock")) {
+		if (strcasecmp(a->argv[1], "lock") == 0) {
 			/* Lock */
 			ast_str_append(&cmdline, 0, ",L");
 		} else {
 			/* Unlock */
 			ast_str_append(&cmdline, 0, ",l");
 		}
-	} else if (strstr(a->argv[1], "mute")) { 
-		if (a->argc < 4) {
-			ast_free(cmdline);
-			return CLI_SHOWUSAGE;
-		}
-		if (strcmp(a->argv[1], "mute") == 0) {
+	} else if (strcasestr(a->argv[1], "mute")) { 
+		if (strcasecmp(a->argv[1], "mute") == 0) {
 			/* Mute */
-			if (strcmp(a->argv[3], "all") == 0) {
+			if (strcasecmp(a->argv[3], "all") == 0) {
 				ast_str_append(&cmdline, 0, ",N");
 			} else {
 				ast_str_append(&cmdline, 0, ",M,%s", a->argv[3]);	
 			}
 		} else {
 			/* Unmute */
-			if (strcmp(a->argv[3], "all") == 0) {
+			if (strcasecmp(a->argv[3], "all") == 0) {
 				ast_str_append(&cmdline, 0, ",n");
 			} else {
 				ast_str_append(&cmdline, 0, ",m,%s", a->argv[3]);
 			}
 		}
-	} else if (strcmp(a->argv[1], "kick") == 0) {
-		if (a->argc < 4) {
-			ast_free(cmdline);
-			return CLI_SHOWUSAGE;
-		}
-		if (strcmp(a->argv[3], "all") == 0) {
+	} else if (strcasecmp(a->argv[1], "kick") == 0) {
+		if (strcasecmp(a->argv[3], "all") == 0) {
 			/* Kick all */
 			ast_str_append(&cmdline, 0, ",K");
 		} else {
@@ -1599,6 +1613,10 @@
 			ast_str_append(&cmdline, 0, ",k,%s", a->argv[3]);
 		}
 	} else {
+		/*
+		 * Should never get here because it is already filtered by the
+		 * callers.
+		 */
 		ast_free(cmdline);
 		return CLI_SHOWUSAGE;
 	}
@@ -1609,6 +1627,66 @@
 	ast_free(cmdline);
 
 	return CLI_SUCCESS;
+}
+
+static char *meetme_lock_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "meetme {lock|unlock}";
+		e->usage =
+			"Usage: meetme lock|unlock <confno>\n"
+			"       Lock or unlock a conference to new users.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_meetmecmd_lock(a->word, a->pos, a->n);
+	}
+
+	if (a->argc != 3) {
+		return CLI_SHOWUSAGE;
+	}
+
+	return meetme_cmd_helper(a);
+}
+
+static char *meetme_kick_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "meetme kick";
+		e->usage =
+			"Usage: meetme kick <confno> all|<userno>\n"
+			"       Kick a conference or a user in a conference.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_meetmecmd_mute_kick(a->line, a->word, a->pos, a->n);
+	}
+
+	if (a->argc != 4) {
+		return CLI_SHOWUSAGE;
+	}
+
+	return meetme_cmd_helper(a);
+}
+
+static char *meetme_mute_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "meetme {mute|unmute}";
+		e->usage =
+			"Usage: meetme mute|unmute <confno> all|<userno>\n"
+			"       Mute or unmute a conference or a user in a conference.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_meetmecmd_mute_kick(a->line, a->word, a->pos, a->n);
+	}
+
+	if (a->argc != 4) {
+		return CLI_SHOWUSAGE;
+	}
+
+	return meetme_cmd_helper(a);
 }
 
 static const char *sla_hold_str(unsigned int hold_access)
@@ -1770,8 +1848,10 @@
 }
 
 static struct ast_cli_entry cli_meetme[] = {
-	AST_CLI_DEFINE(meetme_cmd, "Execute a command on a conference or conferee"),
-	AST_CLI_DEFINE(meetme_show_cmd, "List all or one conference"),
+	AST_CLI_DEFINE(meetme_kick_cmd, "Kick a conference or a user in a conference."),
+	AST_CLI_DEFINE(meetme_show_cmd, "List all conferences or a specific conference."),
+	AST_CLI_DEFINE(meetme_lock_cmd, "Lock or unlock a conference to new users."),
+	AST_CLI_DEFINE(meetme_mute_cmd, "Mute or unmute a conference or a user in a conference."),
 	AST_CLI_DEFINE(sla_show_trunks, "Show SLA Trunks"),
 	AST_CLI_DEFINE(sla_show_stations, "Show SLA Stations"),
 };
@@ -4241,6 +4321,7 @@
 									}
 								}
 								AST_LIST_UNLOCK(&confs);
+								cnf = NULL;
 								if (!found) {
 									/* At this point, we have a confno_tmp (static conference) that is empty */
 									if ((empty_no_pin && ast_strlen_zero(stringp)) || (!empty_no_pin)) {

Modified: team/oej/oolong-path-support-1.8/apps/app_minivm.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/oolong-path-support-1.8/apps/app_minivm.c?view=diff&rev=375355&r1=375354&r2=375355
==============================================================================
--- team/oej/oolong-path-support-1.8/apps/app_minivm.c (original)
+++ team/oej/oolong-path-support-1.8/apps/app_minivm.c Sun Oct 28 05:34:00 2012
@@ -1229,6 +1229,7 @@
 	char dur[PATH_MAX];
 	char tmp[80] = "/tmp/astmail-XXXXXX";
 	char tmp2[PATH_MAX];
+	char newtmp[PATH_MAX]; /* Only used with volgain */
 	struct timeval now;
 	struct ast_tm tm;
 	struct minivm_zone *the_zone = NULL;
@@ -1268,26 +1269,23 @@
 
 	/* If we have a gain option, process it now with sox */
 	if (type == MVM_MESSAGE_EMAIL && (vmu->volgain < -.001 || vmu->volgain > .001) ) {
-		char newtmp[PATH_MAX];
 		char tmpcmd[PATH_MAX];
 		int tmpfd;
-
-		/**
-		 * XXX
-		 * /bug tmpfd is a leaked fd.  The file is also never unlinked.
-		 *      See app_voicemail.c for how the code works there that
-		 *      doesn't have this bug.
-		 */
 
 		ast_copy_string(newtmp, "/tmp/XXXXXX", sizeof(newtmp));
 		ast_debug(3, "newtmp: %s\n", newtmp);
 		tmpfd = mkstemp(newtmp);
-		if (tmpfd > -1) {
-			snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format);
-			ast_safe_system(tmpcmd);
-			finalfilename = newtmp;
-			ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username);
-		}
+		if (tmpfd < 0) {
+			ast_log(LOG_WARNING, "Failed to create temporary file for volgain: %d\n", errno);
+			ast_free(str1);
+			ast_free(str2);
+			return -1;
+		}
+		snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format);
+		ast_safe_system(tmpcmd);
+		close(tmpfd);
+		finalfilename = newtmp;
+		ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username);
 	} else {
 		finalfilename = ast_strdupa(filename);
 	}

Modified: team/oej/oolong-path-support-1.8/apps/app_mixmonitor.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/oolong-path-support-1.8/apps/app_mixmonitor.c?view=diff&rev=375355&r1=375354&r2=375355
==============================================================================
--- team/oej/oolong-path-support-1.8/apps/app_mixmonitor.c (original)
+++ team/oej/oolong-path-support-1.8/apps/app_mixmonitor.c Sun Oct 28 05:34:00 2012
@@ -105,6 +105,11 @@
 			<para>Records the audio on the current channel to the specified file.</para>
 			<para>This application does not automatically answer and should be preceeded by
 			an application such as Answer or Progress().</para>
+			<note><para>MixMonitor runs as an audiohook. In order to keep it running through
+			a transfer, AUDIOHOOK_INHERIT must be set for the channel which ran mixmonitor.
+			For more information, including dialplan configuration set for using
+			AUDIOHOOK_INHERIT with MixMonitor, see the function documentation for
+			AUDIOHOOK_INHERIT.</para></note>
 			<variablelist>
 				<variable name="MIXMONITOR_FILENAME">
 					<para>Will contain the filename used to record.</para>
@@ -116,6 +121,7 @@
 			<ref type="application">StopMixMonitor</ref>
 			<ref type="application">PauseMonitor</ref>
 			<ref type="application">UnpauseMonitor</ref>
+			<ref type="function">AUDIOHOOK_INHERIT</ref>
 		</see-also>
 	</application>
 	<application name="StopMixMonitor" language="en_US">

Modified: team/oej/oolong-path-support-1.8/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/oolong-path-support-1.8/apps/app_queue.c?view=diff&rev=375355&r1=375354&r2=375355
==============================================================================
--- team/oej/oolong-path-support-1.8/apps/app_queue.c (original)
+++ team/oej/oolong-path-support-1.8/apps/app_queue.c Sun Oct 28 05:34:00 2012
@@ -912,8 +912,6 @@
 
 /*! \brief Persistent Members astdb family */
 static const char * const pm_family = "Queue/PersistentMembers";
-/* The maximum length of each persistent member queue database entry */
-#define PM_MAX_LEN 8192
 
 /*! \brief queues.conf [general] option */
 static int queue_persistent_members = 0;
@@ -1043,6 +1041,7 @@
 	int realtime;                        /*!< Is this member realtime? */
 	int status;                          /*!< Status of queue member */
 	int paused;                          /*!< Are we paused (not accepting calls)? */
+	int queuepos;                        /*!< In what order (pertains to certain strategies) should this member be called? */
 	time_t lastcall;                     /*!< When last successful call was hungup */
 	struct call_queue *lastqueue;	     /*!< Last queue we received a call */
 	unsigned int dead:1;                 /*!< Used to detect members deleted in realtime */
@@ -1262,6 +1261,60 @@
 	return !strcasecmp(q->name, q2->name) ? CMP_MATCH | CMP_STOP : 0;
 }
 
+/*! \internal
+ * \brief ao2_callback, Decreases queuepos of all followers with a queuepos greater than arg.
+ * \param obj the member being acted on
+ * \param arg pointer to an integer containing the position value that was removed and requires reduction for anything above
+ */
+static int queue_member_decrement_followers(void *obj, void *arg, int flag)
+{
+	struct member *mem = obj;
+	int *decrement_followers_after = arg;
+
+	if (mem->queuepos > *decrement_followers_after) {
+		mem->queuepos--;
+	}
+
+	return 0;
+}
+
+/*! \internal
+ * \brief ao2_callback, finds members in a queue marked for deletion and in a cascading fashion runs queue_member_decrement_followers
+ *        on them. This callback should always be ran before performing mass unlinking of delmarked members from queues.
+ * \param obj member being acted on
+ * \param arg pointer to the queue members are being removed from
+ */
+static int queue_delme_members_decrement_followers(void *obj, void *arg, int flag)
+{
+	struct member *mem = obj;
+	struct call_queue *queue = arg;
+	int rrpos = mem->queuepos;
+
+	if (mem->delme) {
+		ao2_callback(queue->members, OBJ_NODATA | OBJ_MULTIPLE, queue_member_decrement_followers, &rrpos);
+	}
+
+	return 0;
+}
+
+/*! \internal
+ * \brief Use this to decrement followers during removal of a member
+ * \param queue which queue the member is being removed from
+ * \param mem which member is being removed from the queue
+ */
+static void queue_member_follower_removal(struct call_queue *queue, struct member *mem)
+{
+	int pos = mem->queuepos;
+
+	/* If the position being removed is less than the current place in the queue, reduce the queue position by one so that we don't skip the member
+	 * who would have been next otherwise. */
+	if (pos < queue->rrpos) {
+		queue->rrpos--;
+	}
+
+	ao2_callback(queue->members, OBJ_NODATA | OBJ_MULTIPLE, queue_member_decrement_followers, &pos);
+}
+
 #ifdef REF_DEBUG_ONLY_QUEUES
 #define queue_ref(a)	__ao2_ref_debug(a,1,"",__FILE__,__LINE__,__PRETTY_FUNCTION__)
 #define queue_unref(a)	__ao2_ref_debug(a,-1,"",__FILE__,__LINE__,__PRETTY_FUNCTION__)
@@ -2080,6 +2133,34 @@
 	}
 }
 
+/*! \internal
+ * \brief If adding a single new member to a queue, use this function instead of ao2_linking.
+ *        This adds round robin queue position data for a fresh member as well as links it.
+ * \param queue Which queue the member is being added to
+ * \param mem Which member is being added to the queue
+ */
+static void member_add_to_queue(struct call_queue *queue, struct member *mem)
+{
+	ao2_lock(queue->members);
+	mem->queuepos = ao2_container_count(queue->members);
+	ao2_link(queue->members, mem);
+	ao2_unlock(queue->members);
+}
+
+/*! \internal
+ * \brief If removing a single member from a queue, use this function instead of ao2_unlinking.
+ *        This will perform round robin queue position reordering for the remaining members.
+ * \param queue Which queue the member is being removed from
+ * \param member Which member is being removed from the queue
+ */
+static void member_remove_from_queue(struct call_queue *queue, struct member *mem)
+{
+	ao2_lock(queue->members);
+	queue_member_follower_removal(queue, mem);
+	ao2_unlink(queue->members, mem);
+	ao2_unlock(queue->members);
+}
+
 /*!
  * \brief Find rt member record to update otherwise create one.
  *
@@ -2138,7 +2219,7 @@
 			m->realtime = 1;
 			ast_copy_string(m->rt_uniqueid, rt_uniqueid, sizeof(m->rt_uniqueid));
 			ast_queue_log(q->name, "REALTIME", m->interface, "ADDMEMBER", "%s", paused ? "PAUSED" : "");
-			ao2_link(q->members, m);
+			member_add_to_queue(q, m);
 			ao2_ref(m, -1);
 			m = NULL;
 		}
@@ -2154,7 +2235,7 @@
 
 	while ((cur = ao2_iterator_next(&mem_iter))) {
 		if (all || !cur->dynamic) {
-			ao2_unlink(q->members, cur);
+			member_remove_from_queue(q, cur);
 		}
 		ao2_ref(cur, -1);
 	}
@@ -2319,7 +2400,7 @@
 	while ((m = ao2_iterator_next(&mem_iter))) {
 		if (m->dead) {
 			ast_queue_log(q->name, "REALTIME", m->interface, "REMOVEMEMBER", "%s", "");
-			ao2_unlink(q->members, m);
+			member_remove_from_queue(q, m);
 		}
 		ao2_ref(m, -1);
 	}
@@ -2415,7 +2496,7 @@
 		mem_iter = ao2_iterator_init(q->members, 0);
 		while ((m = ao2_iterator_next(&mem_iter))) {
 			if (m->realtime) {
-				ao2_unlink(q->members, m);
+				member_remove_from_queue(q, m);
 			}
 			ao2_ref(m, -1);
 		}
@@ -2449,7 +2530,7 @@
 	while ((m = ao2_iterator_next(&mem_iter))) {
 		if (m->dead) {
 			ast_queue_log(q->name, "REALTIME", m->interface, "REMOVEMEMBER", "%s", "");
-			ao2_unlink(q->members, m);
+			member_remove_from_queue(q, m);
 		}
 		ao2_ref(m, -1);
 	}
@@ -3878,13 +3959,6 @@
 				return NULL;
 			}
 
-			/*!
-			 * \todo
-			 * XXX Queue like Dial really should send any connected line
-			 * updates (AST_CONTROL_CONNECTED_LINE) from the caller to each
-			 * ringing queue member.
-			 */
-
 			if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass.integer == '*')) {
 				ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
 				*to = 0;
@@ -3898,6 +3972,38 @@
 				ast_frfree(f);
 				return NULL;
 			}
+
+			/* Send the frame from the in channel to all outgoing channels. */
+			for (o = start; o; o = o->call_next) {
+				if (!o->stillgoing || !o->chan) {
+					/* This outgoing channel has died so don't send the frame to it. */
+					continue;
+				}
+				switch (f->frametype) {
+				case AST_FRAME_CONTROL:
+					switch (f->subclass.integer) {
+					case AST_CONTROL_CONNECTED_LINE:
+						if (ast_channel_connected_line_macro(in, o->chan, f, 0, 1)) {
+							ast_indicate_data(o->chan, f->subclass.integer, f->data.ptr, f->datalen);
+						}
+						break;
+					case AST_CONTROL_REDIRECTING:
+						if (ast_channel_redirecting_macro(in, o->chan, f, 0, 1)) {
+							ast_indicate_data(o->chan, f->subclass.integer, f->data.ptr, f->datalen);
+						}
+						break;
+					default:
+						/* We are not going to do anything with this frame. */
+						goto skip_frame;
+					}
+					break;
+				default:
+					/* We are not going to do anything with this frame. */
+					goto skip_frame;
+				}
+			}
+skip_frame:;
+
 			ast_frfree(f);
 		}
 		if (!*to) {
@@ -4160,6 +4266,7 @@
 		break;
 	case QUEUE_STRATEGY_RRORDERED:
 	case QUEUE_STRATEGY_RRMEMORY:
+		pos = mem->queuepos;
 		if (pos < q->rrpos) {
 			tmp->metric = 1000 + pos;
 		} else {
@@ -4543,7 +4650,7 @@
 				callattempt_free(tmp);
 				ao2_ref(cur, -1);
 				ao2_iterator_destroy(&memi);
-				ao2_unlock(&qe->parent);
+				ao2_unlock(qe->parent);
 				goto out;
 			}
 			datastore->data = dialed_interfaces;
@@ -5222,15 +5329,18 @@
 static void dump_queue_members(struct call_queue *pm_queue)
 {
 	struct member *cur_member;
-	char value[PM_MAX_LEN];
-	int value_len = 0;
-	int res;
+	struct ast_str *value;
 	struct ao2_iterator mem_iter;
 
-	memset(value, 0, sizeof(value));
-
-	if (!pm_queue)
+	if (!pm_queue) {
 		return;
+	}
+
+	/* 4K is a reasonable default for most applications, but we grow to
+	 * accommodate more if necessary. */
+	if (!(value = ast_str_create(4096))) {
+		return;
+	}
 
 	mem_iter = ao2_iterator_init(pm_queue->members, 0);
 	while ((cur_member = ao2_iterator_next(&mem_iter))) {
@@ -5239,25 +5349,27 @@
 			continue;
 		}
 
-		res = snprintf(value + value_len, sizeof(value) - value_len, "%s%s;%d;%d;%s;%s",
-			value_len ? "|" : "", cur_member->interface, cur_member->penalty, cur_member->paused, cur_member->membername, cur_member->state_interface);
+		ast_str_append(&value, 0, "%s%s;%d;%d;%s;%s",
+			ast_str_strlen(value) ? "|" : "",
+			cur_member->interface,
+			cur_member->penalty,
+			cur_member->paused,
+			cur_member->membername,
+			cur_member->state_interface);
 
 		ao2_ref(cur_member, -1);
-
-		if (res != strlen(value + value_len)) {
-			ast_log(LOG_WARNING, "Could not create persistent member string, out of space\n");
-			break;
-		}
-		value_len += res;
 	}
 	ao2_iterator_destroy(&mem_iter);
-	
-	if (value_len && !cur_member) {
-		if (ast_db_put(pm_family, pm_queue->name, value))
+
+	if (ast_str_strlen(value) && !cur_member) {
+		if (ast_db_put(pm_family, pm_queue->name, ast_str_buffer(value)))
 			ast_log(LOG_WARNING, "failed to create persistent dynamic entry!\n");
-	} else
+	} else {
 		/* Delete the entry if the queue is empty or there is an error */
 		ast_db_del(pm_family, pm_queue->name);
+	}
+
+	ast_free(value);
 }
 
 /*! \brief Remove member from queue 
@@ -5290,7 +5402,7 @@
 				"Location: %s\r\n"
 				"MemberName: %s\r\n",
 				q->name, mem->interface, mem->membername);
-			ao2_unlink(q->members, mem);
+			member_remove_from_queue(q, mem);
 			ao2_ref(mem, -1);
 
 			if (queue_persistent_members)
@@ -5329,7 +5441,7 @@
 	if ((old_member = interface_exists(q, interface)) == NULL) {

[... 8082 lines stripped ...]



More information about the asterisk-commits mailing list