[asterisk-commits] dhubbard: branch dhubbard/named_processors r110081 - in /team/dhubbard/named_...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Mar 19 15:30:04 CDT 2008


Author: dhubbard
Date: Wed Mar 19 15:30:03 2008
New Revision: 110081

URL: http://svn.digium.com/view/asterisk?view=rev&rev=110081
Log:
merged and resolved conflicts.  yay

Modified:
    team/dhubbard/named_processors/   (props changed)
    team/dhubbard/named_processors/CHANGES
    team/dhubbard/named_processors/Makefile
    team/dhubbard/named_processors/apps/app_chanspy.c
    team/dhubbard/named_processors/apps/app_queue.c
    team/dhubbard/named_processors/build_tools/cflags.xml
    team/dhubbard/named_processors/channels/chan_sip.c
    team/dhubbard/named_processors/channels/chan_zap.c
    team/dhubbard/named_processors/configs/res_ldap.conf.sample
    team/dhubbard/named_processors/include/asterisk/_private.h
    team/dhubbard/named_processors/include/asterisk/http.h
    team/dhubbard/named_processors/main/config.c
    team/dhubbard/named_processors/main/http.c
    team/dhubbard/named_processors/main/manager.c
    team/dhubbard/named_processors/main/pbx.c
    team/dhubbard/named_processors/main/rtp.c
    team/dhubbard/named_processors/main/taskprocessor.c
    team/dhubbard/named_processors/main/utils.c
    team/dhubbard/named_processors/res/res_config_ldap.c
    team/dhubbard/named_processors/res/res_musiconhold.c
    team/dhubbard/named_processors/res/res_phoneprov.c

Propchange: team/dhubbard/named_processors/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/dhubbard/named_processors/
------------------------------------------------------------------------------
    svnautomerge = *

Propchange: team/dhubbard/named_processors/
            ('svnmerge-blocked' removed)

Propchange: team/dhubbard/named_processors/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Mar 19 15:30:03 2008
@@ -1,1 +1,1 @@
-/trunk:1-109686
+/trunk:1-110079

Modified: team/dhubbard/named_processors/CHANGES
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/CHANGES?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/CHANGES (original)
+++ team/dhubbard/named_processors/CHANGES Wed Mar 19 15:30:03 2008
@@ -11,6 +11,12 @@
 ----------------------------------------
  * Channels can now be configured using named sections in zapata.conf, just
    like other channel drivers, including the use of templates.
+
+PBX Changes
+-----------
+ * It is now possible to specify a pattern match as a hint. Once a phone subscribes
+   to something that matches the pattern a hint will be created using the contents
+   and variables evaluated.
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 1.4.X to Asterisk 1.6.0  -------------

Modified: team/dhubbard/named_processors/Makefile
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/Makefile?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/Makefile (original)
+++ team/dhubbard/named_processors/Makefile Wed Mar 19 15:30:03 2008
@@ -847,7 +847,7 @@
 menuselect/makeopts:
 	$(MAKE_MENUSELECT) makeopts
 
-menuselect-tree: $(foreach dir,$(filter-out main,$(MOD_SUBDIRS)),$(wildcard $(dir)/*.c) $(wildcard $(dir)/*.cc)) build_tools/cflags.xml sounds/sounds.xml build_tools/embed_modules.xml configure
+menuselect-tree: $(foreach dir,$(filter-out main,$(MOD_SUBDIRS)),$(wildcard $(dir)/*.c) $(wildcard $(dir)/*.cc)) build_tools/cflags.xml build_tools/cflags-devmode.xml sounds/sounds.xml build_tools/embed_modules.xml configure
 	@echo "Generating input for menuselect ..."
 	@echo "<?xml version=\"1.0\"?>" > $@
 	@echo >> $@
@@ -855,6 +855,9 @@
 	@for dir in $(sort $(filter-out main,$(MOD_SUBDIRS))); do $(SUBMAKE) -C $${dir} SUBDIR=$${dir} moduleinfo >> $@; done
 	@for dir in $(sort $(filter-out main,$(MOD_SUBDIRS))); do $(SUBMAKE) -C $${dir} SUBDIR=$${dir} makeopts >> $@; done
 	@cat build_tools/cflags.xml >> $@
+	@if [ "${AST_DEVMODE}" = "yes" ]; then \
+		cat build_tools/cflags-devmode.xml >> $@; \
+	fi
 	@cat build_tools/embed_modules.xml >> $@
 	@cat sounds/sounds.xml >> $@
 	@echo "</menu>" >> $@

Modified: team/dhubbard/named_processors/apps/app_chanspy.c
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/apps/app_chanspy.c?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/apps/app_chanspy.c (original)
+++ team/dhubbard/named_processors/apps/app_chanspy.c Wed Mar 19 15:30:03 2008
@@ -714,8 +714,10 @@
 					res = ast_streamfile(chan, peer_name, chan->language);
 					if (!res)
 						res = ast_waitstream(chan, "");
-					if (res)
+					if (res) {
+						chanspy_ds_free(peer_chanspy_ds);
 						break;
+					}
 				} else
 					res = ast_say_character_str(chan, peer_name, "", chan->language);
 				if ((num = atoi(ptr)))
@@ -731,6 +733,7 @@
 				goto exit;
 			} else if (res == -2) {
 				res = 0;
+				chanspy_ds_free(peer_chanspy_ds);
 				goto exit;
 			} else if (res > 1 && spec) {
 				struct ast_channel *next;

Modified: team/dhubbard/named_processors/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/apps/app_queue.c?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/apps/app_queue.c (original)
+++ team/dhubbard/named_processors/apps/app_queue.c Wed Mar 19 15:30:03 2008
@@ -680,68 +680,31 @@
  * Lock interface list find sc, iterate through each queues queue_member list for member to
  * update state inside queues
 */
-static int handle_statechange(struct a_task* task)
-{
+static int update_status(const char *interface, const int status)
+{
+	struct member *cur;
+	struct ao2_iterator mem_iter, queue_iter;
 	struct call_queue *q;
-	struct member *cur;
-	struct ao2_iterator mem_iter;
-	struct member_interface *curint;
-	struct ao2_iterator queue_iter;
-	char *loc;
-	char *technology;
-	struct statechange *sc = task->_datap;
-
-	technology = ast_strdupa(sc->dev);
-	loc = strchr(technology, '/');
-	if (loc) {
-		*loc++ = '\0';
-	} else {
-		ast_free(sc);
-		task->_datap = NULL;
-		return 0;
-	}
-
-	AST_LIST_LOCK(&interfaces);
-	AST_LIST_TRAVERSE(&interfaces, curint, list) {
-		char *interface;
-		char *slash_pos;
-		interface = ast_strdupa(curint->interface);
-		if ((slash_pos = strchr(interface, '/')))
-			if ((slash_pos = strchr(slash_pos + 1, '/')))
-				*slash_pos = '\0';
-
-		if (!strcasecmp(interface, sc->dev))
-			break;
-	}
-	AST_LIST_UNLOCK(&interfaces);
-
-	if (!curint) {
-		ast_debug(3, "Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n", technology, loc, sc->state, devstate2str(sc->state));
-		ast_free(sc);
-		task->_datap = NULL;
-		return 0;
-	}
-
-	ast_debug(1, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
+
 	queue_iter = ao2_iterator_init(queues, 0);
 	while ((q = ao2_iterator_next(&queue_iter))) {
 		ao2_lock(q);
 		mem_iter = ao2_iterator_init(q->members, 0);
 		while ((cur = ao2_iterator_next(&mem_iter))) {
-			char *interface;
+			char *tmp_interface;
 			char *slash_pos;
-			interface = ast_strdupa(cur->state_interface);
+			tmp_interface = ast_strdupa(cur->state_interface);
 			if ((slash_pos = strchr(interface, '/')))
 				if ((slash_pos = strchr(slash_pos + 1, '/')))
 					*slash_pos = '\0';
 
-			if (strcasecmp(sc->dev, interface)) {
+			if (strcasecmp(interface, tmp_interface)) {
 				ao2_ref(cur, -1);
 				continue;
 			}
 
-			if (cur->status != sc->state) {
-				cur->status = sc->state;
+			if (cur->status != status) {
+				cur->status = status;
 				if (q->maskmemberstatus) {
 					ao2_ref(cur, -1);
 					continue;
@@ -765,6 +728,52 @@
 		queue_unref(q);
 		ao2_unlock(q);
 	}
+
+	return 0;
+}
+
+/*! \brief set a member's status based on device state of that member's interface*/
+static int handle_statechange(struct a_task *task)
+{
+	struct member_interface *curint;
+	char *loc;
+	char *technology;
+	struct statechange *sc = task->_datap;
+
+	technology = ast_strdupa(sc->dev);
+	loc = strchr(technology, '/');
+	if (loc) {
+		*loc++ = '\0';
+	} else {
+		ast_free(sc);
+		task->_datap = NULL;
+		return 0;
+	}
+
+	AST_LIST_LOCK(&interfaces);
+	AST_LIST_TRAVERSE(&interfaces, curint, list) {
+		char *interface;
+		char *slash_pos;
+		interface = ast_strdupa(curint->interface);
+		if ((slash_pos = strchr(interface, '/')))
+			if ((slash_pos = strchr(slash_pos + 1, '/')))
+				*slash_pos = '\0';
+
+		if (!strcasecmp(interface, sc->dev))
+			break;
+	}
+	AST_LIST_UNLOCK(&interfaces);
+
+	if (!curint) {
+		if (option_debug > 2)
+			ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n", technology, loc, sc->state, devstate2str(sc->state));
+		return 0;
+	}
+
+	if (option_debug)
+		ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
+
+	update_status(sc->dev, sc->state);
 	ast_free(sc);
 	task->_datap = NULL;
 	return 0;
@@ -1944,55 +1953,6 @@
 	}
 }
 
-static int update_status(struct call_queue *q, struct member *member, int status)
-{
-	struct member *cur;
-	struct ao2_iterator mem_iter;
-
-	/* Since a reload could have taken place, we have to traverse the list to
-		be sure it's still valid */
-	ao2_lock(q);
-	mem_iter = ao2_iterator_init(q->members, 0);
-	while ((cur = ao2_iterator_next(&mem_iter))) {
-		if (member != cur) {
-			ao2_ref(cur, -1);
-			continue;
-		}
-
-		cur->status = status;
-		if (!q->maskmemberstatus) {
-			manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
-				"Queue: %s\r\n"
-				"Location: %s\r\n"
-				"MemberName: %s\r\n"
-				"Membership: %s\r\n"
-				"Penalty: %d\r\n"
-				"CallsTaken: %d\r\n"
-				"LastCall: %d\r\n"
-				"Status: %d\r\n"
-				"Paused: %d\r\n",
-				q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime": "static",
-				cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
-		}
-		ao2_ref(cur, -1);
-	}
-	ao2_unlock(q);
-	return 0;
-}
-
-static int update_dial_status(struct call_queue *q, struct member *member, int status)
-{
-	if (status == AST_CAUSE_BUSY)
-		status = AST_DEVICE_BUSY;
-	else if (status == AST_CAUSE_UNREGISTERED)
-		status = AST_DEVICE_UNAVAILABLE;
-	else if (status == AST_CAUSE_NOSUCHDRIVER)
-		status = AST_DEVICE_INVALID;
-	else
-		status = AST_DEVICE_UNKNOWN;
-	return update_status(q, member, status);
-}
-
 /*! 
  * \brief traverse all defined queues which have calls waiting and contain this member
  * \retval 0 if no other queue has precedence (higher weight) 
@@ -2149,7 +2109,8 @@
 		if (qe->chan->cdr)
 			ast_cdr_busy(qe->chan->cdr);
 		tmp->stillgoing = 0;
-		update_dial_status(qe->parent, tmp->member, status);
+
+		update_status(tmp->member->state_interface, ast_device_state(tmp->member->state_interface));
 
 		ao2_lock(qe->parent);
 		qe->parent->rrpos++;
@@ -2159,8 +2120,7 @@
 
 		(*busies)++;
 		return 0;
-	} else if (status != tmp->oldstatus)
-		update_dial_status(qe->parent, tmp->member, status);
+	}
 	
 	tmp->chan->appl = "AppQueue";
 	tmp->chan->data = "(Outgoing Line)";
@@ -2529,8 +2489,6 @@
 					ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
 					/* Setup parameters */
 					o->chan = ast_request(tech, in->nativeformats, stuff, &status);
-					if (status != o->oldstatus)
-						update_dial_status(qe->parent, o->member, status);						
 					if (!o->chan) {
 						ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
 						o->stillgoing = 0;
@@ -3243,8 +3201,8 @@
 		to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
 	orig = to;
 	++qe->pending;
+	ao2_unlock(qe->parent);
 	ring_one(qe, outgoing, &numbusies);
-	ao2_unlock(qe->parent);
 	if (use_weight)
 		ao2_unlock(queues);
 	lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);

Modified: team/dhubbard/named_processors/build_tools/cflags.xml
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/build_tools/cflags.xml?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/build_tools/cflags.xml (original)
+++ team/dhubbard/named_processors/build_tools/cflags.xml Wed Mar 19 15:30:03 2008
@@ -16,8 +16,6 @@
 		</member>
 		<member name="LOTS_OF_SPANS" displayname="More than 32 Zaptel spans">
 		</member>
-		<member name="MTX_PROFILE" displayname="Enable Code Profiling Using TSC Counters">
-		</member>
 		<member name="RADIO_RELAX" displayname="Relax DTMF for Radio Applications">
 		</member>
 		<member name="G711_NEW_ALGORITHM" displayname="Use the NEW ulaw/alaw codecs (slower, but cleaner)">
@@ -35,22 +33,7 @@
 		</member>
 		<member name="DEBUG_CHANNEL_LOCKS" displayname="Debug Channel Locking">
 		</member>
-		<member name="DEBUG_SCHEDULER" displayname="Enable Scheduler Debugging Output">
-		</member>
-		<member name="DEBUG_THREADLOCALS" displayname="Enable Thread-Local-Storage Debugging">
-		</member>
-		<member name="DETECT_DEADLOCKS" displayname="Detect Deadlocks">
-			<depend>DEBUG_THREADS</depend>
-		</member>
-		<member name="DUMP_SCHEDULER" displayname="Dump Scheduler Contents for Debugging">
-		</member>
 		<member name="MALLOC_DEBUG" displayname="Keep Track of Memory Allocations">
-		</member>
-		<member name="TRACE_FRAMES" displayname="Trace Frame Allocations">
-		</member>
-		<member name="DO_CRASH" displayname="Crash on fatal errors">
-		</member>
-		<member name="THREAD_CRASH" displayname="Crash on mutex errors">
 		</member>
 		<member name="BUSYDETECT_TONEONLY" displayname="Enable additional comparision of only the tone duration not the silence part">
 			<conflict>BUSYDETECT_COMPARE_TONE_AND_SILENCE</conflict>
@@ -63,6 +46,4 @@
 		<member name="BUSYDETECT_DEBUG" displayname="Enable additional busy detection debugging">
 			<defaultenabled>no</defaultenabled>
 		</member>
-		<member name="CHANNEL_TRACE" displayname="Enable CHANNEL(trace) function">
-		</member>
 	</category>

Modified: team/dhubbard/named_processors/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/channels/chan_sip.c?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/channels/chan_sip.c (original)
+++ team/dhubbard/named_processors/channels/chan_sip.c Wed Mar 19 15:30:03 2008
@@ -3100,6 +3100,7 @@
 		 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
 		__sip_xmit(p, req->data, req->len);
 	ast_free(req->data);
+	req->data = NULL;
 	if (res > 0)
 		return 0;
 	return res;
@@ -3133,8 +3134,10 @@
 	res = (reliable) ?
 		__sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
 		__sip_xmit(p, req->data, req->len);
-	if (req->data)
+	if (req->data) {
 		ast_free(req->data);
+		req->data = NULL;
+	}
 	return res;
 }
 
@@ -18102,6 +18105,7 @@
 
 	if (req->headers < 2) {	/* Must have at least two headers */
 		ast_free(req->data);
+		req->data = NULL;
 		return 1;
 	}
 

Modified: team/dhubbard/named_processors/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/channels/chan_zap.c?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/channels/chan_zap.c (original)
+++ team/dhubbard/named_processors/channels/chan_zap.c Wed Mar 19 15:30:03 2008
@@ -14105,7 +14105,7 @@
 		ast_mutex_unlock(&iflock);
 		ast_config_destroy(cfg);
 		if (ucfg) {
-			ast_config_destroy(cfg);
+			ast_config_destroy(ucfg);
 		}
 		return res;
 	}

Modified: team/dhubbard/named_processors/configs/res_ldap.conf.sample
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/configs/res_ldap.conf.sample?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/configs/res_ldap.conf.sample (original)
+++ team/dhubbard/named_processors/configs/res_ldap.conf.sample Wed Mar 19 15:30:03 2008
@@ -3,7 +3,7 @@
 ;
 
 ; Sample Asterisk config file for res_config_ldap
-; in extconfig.conf you can use it like this:
+; in extconfig.conf; you can use it like this:
 ; sipusers = ldap,"dc=myDomain,dc=myDomainExt",sip
 ; sippeers = ldap,"dc=myDomain,dc=myDomainExt",sip
 ; extensions = ldap,"dc=myDomain,dc=myDomainExt",extensions
@@ -11,20 +11,29 @@
 
 
 [_general]
-;host=192.168.1.1,ldap.mydomain.com	; LDAP host(s)
-;protocol=3		; Version of the LDAP protocol to use default is 3.
-;basedn=MyRootDN	; Base DN
-;pass=MyPassword	; Bind password
-;user=MyDN		; Bind DN
+;
+; Specify one of either host and port OR url.  URL is preferred, as you can
+; use more options.
+;host=192.168.1.1                    ; LDAP host
+;port=389
+;url=ldap://ldap3.mydomain.com:3890
+;protocol=3                          ; Version of the LDAP protocol to use; default is 3.
+;basedn=MyRootDN                     ; Base DN
+;user=MyDN                           ; Bind DN
+;pass=MyPassword                     ; Bind password
 
 ; Configuration Table
 [config]
-; addtional filter - This specifies an additional set of criteria to be used
+;
+; additionalFilter - This specifies an additional set of criteria to be used
 ; when querying the LDAP server.
+;
 additionalFilter=(objectClass=PBXConfig)
+;
 ; Attributes mapping (asterisk variable name = ldap attribute name)
 ; When Asterisk requests the variable by the name of the value on the left,
 ; this module will look up the attribute listed on the right.
+;
 filename = PBXConfigFilename
 category = PBXConfigCategory
 variable_name = PBXConfigVariableName
@@ -32,7 +41,9 @@
 cat_metric = PBXConfigCategoryMetric
 commented = PBXConfigCommented
 
+;
 ; Extensions Table
+;
 [extensions]
 context  =  PBXExtensionContext
 exten  =  PBXExtensionExten
@@ -41,7 +52,9 @@
 appdata = PBXExtensionApplicationData
 additionalFilter=(objectClass=PBXExtension)
 
+;
 ; Sip Users Table
+;
 [sip]
 name = uid
 amaflags = PBXAccountAMAFlags
@@ -77,7 +90,9 @@
 CanCallForward = PBXAccountCanCallForward
 additionalFilter=(objectClass=PBXAccountSIP)
 
+;
 ; IAX Users Table
+;
 [iax]
 amaflags = PBXAccountAMAFlags
 callerid = PBXAccountCallerID
@@ -100,7 +115,9 @@
 notransfer = PBXAccountNoTransfer
 additionalFilter=(objectClass=PBXAccountIAX)
 
+;
 ; A Test Family
+;
 [testfamily]
 MyUSERID = uid
 additionalFilter=(objectClass=*)

Modified: team/dhubbard/named_processors/include/asterisk/_private.h
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/include/asterisk/_private.h?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/include/asterisk/_private.h (original)
+++ team/dhubbard/named_processors/include/asterisk/_private.h Wed Mar 19 15:30:03 2008
@@ -33,7 +33,9 @@
 int astobj2_init(void);			/*!< Provided by astobj2.c */
 int ast_file_init(void);		/*!< Provided by file.c */
 int ast_features_init(void);            /*!< Provided by features.c */
-void ast_autoservice_init(void);    /*!< Provided by autoservice.c */
+void ast_autoservice_init(void);	/*!< Provided by autoservice.c */
+int ast_http_init(void);		/*!< Provided by http.c */
+int ast_http_reload(void);		/*!< Provided by http.c */
 
 /*!
  * \brief Reload asterisk modules.

Modified: team/dhubbard/named_processors/include/asterisk/http.h
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/include/asterisk/http.h?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/include/asterisk/http.h (original)
+++ team/dhubbard/named_processors/include/asterisk/http.h Wed Mar 19 15:30:03 2008
@@ -65,29 +65,37 @@
    content is specified) 
 \endverbatim
 */
-typedef struct ast_str *(*ast_http_callback)(struct ast_tcptls_session_instance *ser, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength);
 
-/*! \brief Definition of a URI reachable in the embedded HTTP server */
+enum ast_http_method {
+	AST_HTTP_GET = 0,
+	AST_HTTP_POST,
+};
+
+typedef struct ast_str *(*ast_http_callback)(struct ast_tcptls_session_instance *ser, const char *uri, enum ast_http_method method,
+					     struct ast_variable *params, int *status, char **title, int *contentlength);
+
+/*! \brief Definition of a URI handler */
 struct ast_http_uri {
 	AST_LIST_ENTRY(ast_http_uri) entry;
 	const char *description;
 	const char *uri;
+	ast_http_callback callback;
 	unsigned int has_subtree:1;
-	/*! This URI mapping serves static content */
+	/*! This handler serves static content */
 	unsigned int static_content:1;
-	ast_http_callback callback;
+	/*! This handler accepts GET requests */
+	unsigned int supports_get:1;
+	/*! This handler accepts POST requests */
+	unsigned int supports_post:1;
 };
 
-/*! \brief Link into the Asterisk HTTP server */
+/*! \brief Register a URI handler */
 int ast_http_uri_link(struct ast_http_uri *urihandler);
+
+/*! \brief Unregister a URI handler */
+void ast_http_uri_unlink(struct ast_http_uri *urihandler);
 
 /*! \brief Return an ast_str malloc()'d string containing an HTTP error message */
 struct ast_str *ast_http_error(int status, const char *title, const char *extra_header, const char *text);
 
-/*! \brief Destroy an HTTP server */
-void ast_http_uri_unlink(struct ast_http_uri *urihandler);
-
-int ast_http_init(void);
-int ast_http_reload(void);
-
 #endif /* _ASTERISK_SRV_H */

Modified: team/dhubbard/named_processors/main/config.c
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/main/config.c?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/main/config.c (original)
+++ team/dhubbard/named_processors/main/config.c Wed Mar 19 15:30:03 2008
@@ -1621,15 +1621,21 @@
 			if (!cat->precomments)
 				fprintf(f,"\n");
 			fprintf(f, "[%s]", cat->name);
-			if (cat->ignored)
-				fprintf(f, "(!)");
-			if (!AST_LIST_EMPTY(&cat->template_instances)) {
-				struct ast_category_template_instance *x;
+			if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) {
 				fprintf(f, "(");
-				AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
-					fprintf(f,"%s",x->name);
-					if (x != AST_LIST_LAST(&cat->template_instances))
-						fprintf(f,",");
+				if (cat->ignored) {
+					fprintf(f, "!");
+				}
+				if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) {
+					fprintf(f, ",");
+				}
+				if (!AST_LIST_EMPTY(&cat->template_instances)) {
+					struct ast_category_template_instance *x;
+					AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
+						fprintf(f,"%s",x->name);
+						if (x != AST_LIST_LAST(&cat->template_instances))
+							fprintf(f,",");
+					}
 				}
 				fprintf(f, ")");
 			}

Modified: team/dhubbard/named_processors/main/http.c
URL: http://svn.digium.com/view/asterisk/team/dhubbard/named_processors/main/http.c?view=diff&rev=110081&r1=110080&r2=110081
==============================================================================
--- team/dhubbard/named_processors/main/http.c (original)
+++ team/dhubbard/named_processors/main/http.c Wed Mar 19 15:30:03 2008
@@ -32,8 +32,6 @@
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
-#include "asterisk/paths.h"	/* use ast_config_AST_DATA_DIR */
-#include "asterisk/network.h"
 #include <time.h>
 #include <sys/time.h>
 #include <sys/stat.h>
@@ -44,6 +42,8 @@
 #include <gmime/gmime.h>
 #endif /* ENABLE_UPLOADS */
 
+#include "asterisk/paths.h"	/* use ast_config_AST_DATA_DIR */
+#include "asterisk/network.h"
 #include "asterisk/cli.h"
 #include "asterisk/tcptls.h"
 #include "asterisk/http.h"
@@ -53,6 +53,7 @@
 #include "asterisk/stringfields.h"
 #include "asterisk/ast_version.h"
 #include "asterisk/manager.h"
+#include "asterisk/_private.h"
 
 #define MAX_PREFIX 80
 
@@ -135,17 +136,22 @@
 static const char *ftype2mtype(const char *ftype, char *wkspace, int wkspacelen)
 {
 	int x;
+
 	if (ftype) {
-		for (x=0;x<sizeof(mimetypes) / sizeof(mimetypes[0]); x++) {
-			if (!strcasecmp(ftype, mimetypes[x].ext))
+		for (x = 0; x < ARRAY_LEN(mimetypes); x++) {
+			if (!strcasecmp(ftype, mimetypes[x].ext)) {
 				return mimetypes[x].mtype;
-		}
-	}
-	snprintf(wkspace, wkspacelen, "text/%s", ftype ? ftype : "plain");
+			}
+		}
+	}
+
+	snprintf(wkspace, wkspacelen, "text/%s", S_OR(ftype, "plain"));
+
 	return wkspace;
 }
 
-static struct ast_str *static_callback(struct ast_tcptls_session_instance *ser, const char *uri, struct ast_variable *vars, int *status, char **title, int *contentlength)
+static struct ast_str *static_callback(struct ast_tcptls_session_instance *ser, const char *uri, enum ast_http_method method,
+				       struct ast_variable *vars, int *status, char **title, int *contentlength)
 {
 	char *path;
 	char *ftype;
@@ -160,32 +166,43 @@
 
 	/* Yuck.  I'm not really sold on this, but if you don't deliver static content it makes your configuration 
 	   substantially more challenging, but this seems like a rather irritating feature creep on Asterisk. */
-	if (!enablestatic || ast_strlen_zero(uri))
+	if (!enablestatic || ast_strlen_zero(uri)) {
 		goto out403;
+	}
+
 	/* Disallow any funny filenames at all */
-	if ((uri[0] < 33) || strchr("./|~@#$%^&*() \t", uri[0]))
+	if ((uri[0] < 33) || strchr("./|~@#$%^&*() \t", uri[0])) {
 		goto out403;
-	if (strstr(uri, "/.."))
+	}
+
+	if (strstr(uri, "/..")) {
 		goto out403;
+	}
 		
-	if ((ftype = strrchr(uri, '.')))
+	if ((ftype = strrchr(uri, '.'))) {
 		ftype++;
+	}
+
 	mtype = ftype2mtype(ftype, wkspace, sizeof(wkspace));
 	
 	/* Cap maximum length */
-	len = strlen(uri) + strlen(ast_config_AST_DATA_DIR) + strlen("/static-http/") + 5;
-	if (len > 1024)
+	if ((len = strlen(uri) + strlen(ast_config_AST_DATA_DIR) + strlen("/static-http/") + 5)) {
 		goto out403;
+	}
 		
 	path = alloca(len);
 	sprintf(path, "%s/static-http/%s", ast_config_AST_DATA_DIR, uri);
-	if (stat(path, &st))
+	if (stat(path, &st)) {
 		goto out404;
-	if (S_ISDIR(st.st_mode))
+	}
+
+	if (S_ISDIR(st.st_mode)) {
 		goto out404;
-	fd = open(path, O_RDONLY);
-	if (fd < 0)
+	}
+
+	if ((fd = open(path, O_RDONLY)) < 0) {
 		goto out403;
+	}
 
 	ast_strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S %Z", ast_localtime(&tv, &tm, "GMT"));
 	fprintf(ser->f, "HTTP/1.1 200 OK\r\n"
@@ -197,57 +214,69 @@
 		"Content-type: %s\r\n\r\n",
 		ast_get_version(), buf, (int) st.st_size, mtype);
 
-	while ((len = read(fd, buf, sizeof(buf))) > 0)
+	while ((len = read(fd, buf, sizeof(buf))) > 0) {
 		fwrite(buf, 1, len, ser->f);
+	}
 
 	close(fd);
+
 	return NULL;
 
 out404:
-	*status = 404;
-	*title = ast_strdup("Not Found");
-	return ast_http_error(404, "Not Found", NULL, "Nothing to see here.  Move along.");
+	return ast_http_error((*status = 404),
+			      (*title = ast_strdup("Not Found")),
+			       NULL, "Nothing to see here.  Move along.");
 
 out403:
-	*status = 403;
-	*title = ast_strdup("Access Denied");
-	return ast_http_error(403, "Access Denied", NULL, "Sorry, I cannot let you do that, Dave.");
-}
-
-
-static struct ast_str *httpstatus_callback(struct ast_tcptls_session_instance *ser, const char *uri, struct ast_variable *vars, int *status, char **title, int *contentlength)
+	return ast_http_error((*status = 403),
+			      (*title = ast_strdup("Access Denied")),
+			      NULL, "Sorry, I cannot let you do that, Dave.");
+}
+
+
+static struct ast_str *httpstatus_callback(struct ast_tcptls_session_instance *ser, const char *uri, enum ast_http_method method,
+					   struct ast_variable *vars, int *status, char **title, int *contentlength)
 {
 	struct ast_str *out = ast_str_create(512);
 	struct ast_variable *v;
 
-	if (out == NULL)
+	if (out == NULL) {
 		return out;
+	}
 
 	ast_str_append(&out, 0,
-		"\r\n"
-		"<title>Asterisk HTTP Status</title>\r\n"
-		"<body bgcolor=\"#ffffff\">\r\n"
-		"<table bgcolor=\"#f1f1f1\" align=\"center\"><tr><td bgcolor=\"#e0e0ff\" colspan=\"2\" width=\"500\">\r\n"
-		"<h2>&nbsp;&nbsp;Asterisk&trade; HTTP Status</h2></td></tr>\r\n");
-
+		       "\r\n"
+		       "<title>Asterisk HTTP Status</title>\r\n"
+		       "<body bgcolor=\"#ffffff\">\r\n"
+		       "<table bgcolor=\"#f1f1f1\" align=\"center\"><tr><td bgcolor=\"#e0e0ff\" colspan=\"2\" width=\"500\">\r\n"
+		       "<h2>&nbsp;&nbsp;Asterisk&trade; HTTP Status</h2></td></tr>\r\n");
 	ast_str_append(&out, 0, "<tr><td><i>Prefix</i></td><td><b>%s</b></td></tr>\r\n", prefix);
 	ast_str_append(&out, 0, "<tr><td><i>Bind Address</i></td><td><b>%s</b></td></tr>\r\n",
-			ast_inet_ntoa(http_desc.oldsin.sin_addr));
+		       ast_inet_ntoa(http_desc.oldsin.sin_addr));
 	ast_str_append(&out, 0, "<tr><td><i>Bind Port</i></td><td><b>%d</b></td></tr>\r\n",
-			ntohs(http_desc.oldsin.sin_port));
-	if (http_tls_cfg.enabled)
+		       ntohs(http_desc.oldsin.sin_port));
+
+	if (http_tls_cfg.enabled) {
 		ast_str_append(&out, 0, "<tr><td><i>SSL Bind Port</i></td><td><b>%d</b></td></tr>\r\n",
-			ntohs(https_desc.oldsin.sin_port));
+			       ntohs(https_desc.oldsin.sin_port));
+	}
+
 	ast_str_append(&out, 0, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
+
 	for (v = vars; v; v = v->next) {
-		if (strncasecmp(v->name, "cookie_", 7))
+		if (strncasecmp(v->name, "cookie_", 7)) {
 			ast_str_append(&out, 0, "<tr><td><i>Submitted Variable '%s'</i></td><td>%s</td></tr>\r\n", v->name, v->value);
-	}
+		}
+	}
+
 	ast_str_append(&out, 0, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
+
 	for (v = vars; v; v = v->next) {
-		if (!strncasecmp(v->name, "cookie_", 7))
+		if (!strncasecmp(v->name, "cookie_", 7)) {
 			ast_str_append(&out, 0, "<tr><td><i>Cookie '%s'</i></td><td>%s</td></tr>\r\n", v->name, v->value);
-	}
+		}
+	}
+
 	ast_str_append(&out, 0, "</table><center><font size=\"-1\"><i>Asterisk and Digium are registered trademarks of Digium, Inc.</i></font></center></body>\r\n");
 	return out;
 }
@@ -256,7 +285,7 @@
 	.callback = httpstatus_callback,
 	.description = "Asterisk HTTP General Status",
 	.uri = "httpstatus",
-	.has_subtree = 0,
+	.supports_get = 1,
 };
 	
 static struct ast_http_uri staticuri = {
@@ -265,27 +294,32 @@
 	.uri = "static",
 	.has_subtree = 1,
 	.static_content = 1,
+	.supports_get = 1,
 };
 	
 struct ast_str *ast_http_error(int status, const char *title, const char *extra_header, const char *text)
 {
 	struct ast_str *out = ast_str_create(512);
-	if (out == NULL)
+
+	if (out == NULL) {
 		return out;
+	}
+
 	ast_str_set(&out, 0,
-		"Content-type: text/html\r\n"
-		"%s"
-		"\r\n"
-		"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
-		"<html><head>\r\n"
-		"<title>%d %s</title>\r\n"
-		"</head><body>\r\n"
-		"<h1>%s</h1>\r\n"
-		"<p>%s</p>\r\n"
-		"<hr />\r\n"
-		"<address>Asterisk Server</address>\r\n"
-		"</body></html>\r\n",
-			(extra_header ? extra_header : ""), status, title, title, text);
+		    "Content-type: text/html\r\n"
+		    "%s"
+		    "\r\n"
+		    "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
+		    "<html><head>\r\n"
+		    "<title>%d %s</title>\r\n"
+		    "</head><body>\r\n"
+		    "<h1>%s</h1>\r\n"
+		    "<p>%s</p>\r\n"
+		    "<hr />\r\n"
+		    "<address>Asterisk Server</address>\r\n"
+		    "</body></html>\r\n",
+		    (extra_header ? extra_header : ""), status, title, title, text);
+
 	return out;
 }
 
@@ -303,19 +337,26 @@
 	struct ast_http_uri *uri;
 	int len = strlen(urih->uri);
 
+	if (!(urih->supports_get || urih->supports_post)) {
+		ast_log(LOG_WARNING, "URI handler does not provide either GET or POST method: %s (%s)\n", urih->uri, urih->description);
+		return -1;
+	}
+
 	AST_RWLIST_WRLOCK(&uris);
 
-	if ( AST_RWLIST_EMPTY(&uris) || strlen(AST_RWLIST_FIRST(&uris)->uri) <= len ) {
+	if (AST_RWLIST_EMPTY(&uris) || strlen(AST_RWLIST_FIRST(&uris)->uri) <= len) {
 		AST_RWLIST_INSERT_HEAD(&uris, urih, entry);
 		AST_RWLIST_UNLOCK(&uris);
+
 		return 0;
 	}
 
 	AST_RWLIST_TRAVERSE(&uris, uri, entry) {
-		if ( AST_RWLIST_NEXT(uri, entry) 
-			&& strlen(AST_RWLIST_NEXT(uri, entry)->uri) <= len ) {
+		if (AST_RWLIST_NEXT(uri, entry) &&
+		    strlen(AST_RWLIST_NEXT(uri, entry)->uri) <= len) {
 			AST_RWLIST_INSERT_AFTER(&uris, uri, urih, entry);
 			AST_RWLIST_UNLOCK(&uris); 
+
 			return 0;
 		}
 	}
@@ -342,16 +383,19 @@
 
 	if (!ast_strlen_zero(prefix) && strncmp(prefix, uri, strlen(prefix))) {
 		ast_debug(1, "URI %s does not have prefix %s\n", uri, prefix);
+
 		return NULL;
 	}
 
 	uri += strlen(prefix);
-	if (*uri == '/')
+	if (*uri == '/') {
 		uri++;
+	}
 	
 	AST_RWLIST_TRAVERSE(&post_mappings, post_map, entry) {
-		if (!strcmp(uri, post_map->from))
+		if (!strcmp(uri, post_map->from)) {
 			return post_map;
+		}
 	}
 
 	return NULL;
@@ -370,6 +414,7 @@
 
 	if ((fd = open(filename, O_CREAT | O_WRONLY, 0666)) == -1) {
 		ast_log(LOG_WARNING, "Unable to open %s for writing file from a POST!\n", filename);
+
 		return;
 	}
 
@@ -420,7 +465,7 @@
 		GList *l;
 		
 		ast_log(LOG_WARNING, "Got unexpected GMIME_IS_MULTIPART, trying to process subparts\n");
-		l = GMIME_MULTIPART (part)->subparts;
+		l = GMIME_MULTIPART(part)->subparts;
 		while (l) {
 			process_message_callback(l->data, cbinfo);
 			l = l->next;
@@ -428,7 +473,6 @@
 	} else if (GMIME_IS_PART(part)) {
 		const char *filename;
 
-		ast_debug(3, "Got mime part\n");
 		if (ast_strlen_zero(filename = g_mime_part_get_filename(GMIME_PART(part)))) {
 			ast_debug(1, "Skipping part with no filename\n");
 			return;
@@ -453,8 +497,8 @@
 }
 
 static struct ast_str *handle_post(struct ast_tcptls_session_instance *ser, char *uri, 
-	int *status, char **title, int *contentlength, struct ast_variable *headers,
-	struct ast_variable *cookies)
+				   int *status, char **title, int *contentlength, struct ast_variable *headers,
+				   struct ast_variable *cookies)
 {
 	char buf[4096];
 	FILE *f;
@@ -468,47 +512,52 @@
 	int message_count = 0;
 
 	for (var = cookies; var; var = var->next) {
-		if (strcasecmp(var->name, "mansession_id"))
+		if (strcasecmp(var->name, "mansession_id")) {
 			continue;
+		}
 
 		if (sscanf(var->value, "%lx", &ident) != 1) {
-			*status = 400;
-			*title = ast_strdup("Bad Request");
-			return ast_http_error(400, "Bad Request", NULL, "The was an error parsing the request.");
+			return ast_http_error((*status = 400),
+					      (*title = ast_strdup("Bad Request")),
+					      NULL, "The was an error parsing the request.");
 		}
 
 		if (!astman_verify_session_writepermissions(ident, EVENT_FLAG_CONFIG)) {
-			*status = 401;
-			*title = ast_strdup("Unauthorized");
-			return ast_http_error(401, "Unauthorized", NULL, "You are not authorized to make this request.");
+			return ast_http_error((*status = 401),
+					      (*title = ast_strdup("Unauthorized")),
+					      NULL, "You are not authorized to make this request.");
 		}
 
 		break;
 	}
 	if (!var) {
-		*status = 401;
-		*title = ast_strdup("Unauthorized");
-		return ast_http_error(401, "Unauthorized", NULL, "You are not authorized to make this request.");
-	}
-
-	if (!(f = tmpfile()))
+		return ast_http_error((*status = 401),
+				      (*title = ast_strdup("Unauthorized")),
+				      NULL, "You are not authorized to make this request.");
+	}
+
+	if (!(f = tmpfile())) {
 		return NULL;
+	}
 
 	for (var = headers; var; var = var->next) {
 		if (!strcasecmp(var->name, "Content-Length")) {
 			if ((sscanf(var->value, "%u", &content_len)) != 1) {
 				ast_log(LOG_ERROR, "Invalid Content-Length in POST request!\n");
 				fclose(f);
+
 				return NULL;
 			}
 			ast_debug(1, "Got a Content-Length of %d\n", content_len);
-		} else if (!strcasecmp(var->name, "Content-Type"))
+		} else if (!strcasecmp(var->name, "Content-Type")) {
 			fprintf(f, "Content-Type: %s\r\n\r\n", var->value);
-	}
-
-	for(res = sizeof(buf);content_len;content_len -= res) {
-		if (content_len < res)
+		}
+	}
+
+	for (res = sizeof(buf); content_len; content_len -= res) {
+		if (content_len < res) {
 			res = content_len;
+		}
 		fread(buf, 1, res, ser->f);
 		fwrite(buf, 1, res, f);
 	}
@@ -516,6 +565,7 @@
 	if (fseek(f, SEEK_SET, 0)) {
 		ast_debug(1, "Failed to seek temp file back to beginning.\n");
 		fclose(f);
+
 		return NULL;
 	}
 
@@ -523,10 +573,12 @@
 	if (!(post_map = find_post_mapping(uri))) {
 		ast_debug(1, "%s is not a valid URI for POST\n", uri);
 		AST_RWLIST_UNLOCK(&post_mappings);
-		*status = 404;
-		*title = ast_strdup("Not Found");
-		return ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this server.");
-	}
+
+		return ast_http_error((*status = 404),
+				      (*title = ast_strdup("Not Found")),
+				      NULL, "The requested URL was not found on this server.");
+	}
+
 	post_dir = ast_strdupa(post_map->to);
 	post_map = NULL;
 	AST_RWLIST_UNLOCK(&post_mappings);
@@ -537,121 +589,165 @@
 
 	if (!message) {
 		ast_log(LOG_ERROR, "Error parsing MIME data\n");
-		*status = 400;
-		*title = ast_strdup("Bad Request");
-		return ast_http_error(400, "Bad Request", NULL, "The was an error parsing the request.");
+
+		return ast_http_error((*status = 400),
+				      (*title = ast_strdup("Bad Request")),
+				      NULL, "The was an error parsing the request.");
 	}
 
 	if (!(message_count = process_message(message, post_dir))) {
 		ast_log(LOG_ERROR, "Invalid MIME data, found no parts!\n");
-		*status = 400;
-		*title = ast_strdup("Bad Request");
-		return ast_http_error(400, "Bad Request", NULL, "The was an error parsing the request.");
-	}
-
-	*status = 200;
-	*title = ast_strdup("OK");
-	return ast_http_error(200, "OK", NULL, "File successfully uploaded.");
+
+		return ast_http_error((*status = 400),
+				      (*title = ast_strdup("Bad Request")),
+				      NULL, "The was an error parsing the request.");
+	}
+
+	return ast_http_error((*status = 200),
+			      (*title = ast_strdup("OK")),
+			      NULL, "File successfully uploaded.");
 }
 #endif /* ENABLE_UPLOADS */
 
-static struct ast_str *handle_uri(struct ast_tcptls_session_instance *ser, char *uri, int *status, 
-	char **title, int *contentlength, struct ast_variable **cookies, 
-	unsigned int *static_content)
+static struct ast_str *handle_uri(struct ast_tcptls_session_instance *ser, char *uri, enum ast_http_method method,
+				  int *status, char **title, int *contentlength, struct ast_variable **cookies, 
+				  unsigned int *static_content)
 {
 	char *c;
 	struct ast_str *out = NULL;
 	char *params = uri;
-	struct ast_http_uri *urih=NULL;
+	struct ast_http_uri *urih = NULL;
 	int l;
-	struct ast_variable *vars=NULL, *v, *prev = NULL;
+	struct ast_variable *vars = NULL, *v, *prev = NULL;
 	struct http_uri_redirect *redirect;
-
-	strsep(&params, "?");
-	/* Extract arguments from the request and store them in variables. */
-	if (params) {
-		char *var, *val;
-
-		while ((val = strsep(&params, "&"))) {
-			var = strsep(&val, "=");
-			if (val)
-				ast_uri_decode(val);
-			else 
-				val = "";
-			ast_uri_decode(var);
-			if ((v = ast_variable_new(var, val, ""))) {
-				if (vars)
-					prev->next = v;
-				else
-					vars = v;
-				prev = v;
+	int saw_method = 0;
+
+	/* preserve previous behavior of only support URI parameters on GET requests */
+	if (method == AST_HTTP_GET) {
+		strsep(&params, "?");
+		

[... 1279 lines stripped ...]



More information about the asterisk-commits mailing list