Author: kmoore
Date: Fri Aug 16 12:41:20 2013
New Revision: 396858

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=396858
Log:
Make the parking unloadability work a tad less ugly

Modified:
    team/kmoore/parking_unload/channels/chan_dahdi.c
    team/kmoore/parking_unload/channels/chan_skinny.c
    team/kmoore/parking_unload/channels/sig_analog.c
    team/kmoore/parking_unload/include/asterisk/parking.h
    team/kmoore/parking_unload/main/bridge.c
    team/kmoore/parking_unload/main/bridge_channel.c
    team/kmoore/parking_unload/main/parking.c
    team/kmoore/parking_unload/res/parking/parking_bridge_features.c
    team/kmoore/parking_unload/res/parking/res_parking.h
    team/kmoore/parking_unload/res/res_parking.c

Modified: team/kmoore/parking_unload/channels/chan_dahdi.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/channels/chan_dahdi.c?view=diff&rev=396858&r1=396857&r2=396858
==============================================================================
--- team/kmoore/parking_unload/channels/chan_dahdi.c (original)
+++ team/kmoore/parking_unload/channels/chan_dahdi.c Fri Aug 16 12:41:20 2013
@@ -9246,10 +9246,6 @@
        int idx;
        struct ast_format tmpfmt;
        RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, 
ao2_cleanup);
-       RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
-               ast_parking_get_bridge_features(),
-               ao2_cleanup);
-       int is_exten_parking;
        const char *pickupexten;
 
        ast_mutex_lock(&ss_thread_lock);
@@ -9563,6 +9559,8 @@
                if (p->subs[SUB_THREEWAY].owner)
                        timeout = 999999;
                while (len < AST_MAX_EXTENSION-1) {
+                       int is_exten_parking = 0;
+
                        /* Read digit unless it's supposed to be immediate, in 
which case the
                           only answer is 's' */
                        if (p->immediate)
@@ -9585,7 +9583,9 @@
                        } else {
                                tone_zone_play_tone(p->subs[idx].dfd, 
DAHDI_TONE_DIALTONE);
                        }
-                       is_exten_parking = (parking_provider ? 
parking_provider->parking_is_exten_park(ast_channel_context(chan), exten) : 0);
+                       if (ast_parking_provider_registered()) {
+                               is_exten_parking = 
ast_parking_is_exten_park(ast_channel_context(chan), exten);
+                       }
                        if (ast_exists_extension(chan, 
ast_channel_context(chan), exten, 1, p->cid_num) && !is_exten_parking) {
                                if (!res || !ast_matchmore_extension(chan, 
ast_channel_context(chan), exten, 1, p->cid_num)) {
                                        if (getforward) {
@@ -9730,7 +9730,7 @@
                                ast_channel_lock(chan);
                                bridge_channel = 
ast_channel_get_bridge_channel(chan);
                                ast_channel_unlock(chan);
-                               if (bridge_channel && 
!parking_provider->parking_blind_transfer_park(bridge_channel, 
ast_channel_context(chan), exten)) {
+                               if (bridge_channel && 
!ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), 
exten)) {
                                        ast_verb(3, "Parking call to '%s'\n", 
ast_channel_name(chan));
                                }
                                break;

Modified: team/kmoore/parking_unload/channels/chan_skinny.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/channels/chan_skinny.c?view=diff&rev=396858&r1=396857&r2=396858
==============================================================================
--- team/kmoore/parking_unload/channels/chan_skinny.c (original)
+++ team/kmoore/parking_unload/channels/chan_skinny.c Fri Aug 16 12:41:20 2013
@@ -6409,14 +6409,11 @@
                {
                char extout[AST_MAX_EXTENSION];
                char message[32];
-               RAII_VAR(struct ast_parking_bridge_feature_fn_table *, 
parking_provider,
-                       ast_parking_get_bridge_features(),
-                       ao2_cleanup);
                RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, 
ao2_cleanup);
                SKINNY_DEBUG(DEBUG_PACKET, 3, "Received STIMULUS_CALLPARK from 
%s, inst %d, callref %d\n",
                        d->name, instance, callreference);
 
-               if (!parking_provider) {
+               if (!ast_parking_provider_registered()) {
                        transmit_displaynotify(d, "Call Park not available", 
10);
                        break;
                }
@@ -6432,7 +6429,7 @@
                                break;
                        }
 
-                       if 
(!parking_provider->parking_park_call(bridge_channel, extout, sizeof(extout))) {
+                       if (!ast_parking_park_call(bridge_channel, extout, 
sizeof(extout))) {
                                snprintf(message, sizeof(message), "Call Parked 
at: %s", extout);
                                transmit_displaynotify(d, message, 10);
                                break;
@@ -7159,14 +7156,11 @@
                {
                char extout[AST_MAX_EXTENSION];
                char message[32];
-               RAII_VAR(struct ast_parking_bridge_feature_fn_table *, 
parking_provider,
-                       ast_parking_get_bridge_features(),
-                       ao2_cleanup);
                RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, 
ao2_cleanup);
                SKINNY_DEBUG(DEBUG_PACKET, 3, "Received SOFTKEY_PARK from %s, 
inst %d, callref %d\n",
                        d->name, instance, callreference);
 
-               if (!parking_provider) {
+               if (!ast_parking_provider_registered()) {
                        transmit_displaynotify(d, "Call Park not available", 
10);
                        break;
                }
@@ -7184,7 +7178,7 @@
                                break;
                        }
 
-                       if 
(!parking_provider->parking_park_call(bridge_channel, extout, sizeof(extout))) {
+                       if (!ast_parking_park_call(bridge_channel, extout, 
sizeof(extout))) {
                                snprintf(message, sizeof(message), "Call Parked 
at: %s", extout);
                                transmit_displaynotify(d, message, 10);
                                break;

Modified: team/kmoore/parking_unload/channels/sig_analog.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/channels/sig_analog.c?view=diff&rev=396858&r1=396857&r2=396858
==============================================================================
--- team/kmoore/parking_unload/channels/sig_analog.c (original)
+++ team/kmoore/parking_unload/channels/sig_analog.c Fri Aug 16 12:41:20 2013
@@ -1715,11 +1715,7 @@
        int idx;
        struct ast_callid *callid;
        RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, 
ao2_cleanup);
-       RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
-               ast_parking_get_bridge_features(),
-               ao2_cleanup);
        const char *pickupexten;
-       int is_exten_parking;
 
        analog_increase_ss_count();
 
@@ -2077,6 +2073,8 @@
                        timeout = 999999;
                }
                while (len < AST_MAX_EXTENSION-1) {
+                       int is_exten_parking = 0;
+
                        /* Read digit unless it's supposed to be immediate, in 
which case the
                           only answer is 's' */
                        if (p->immediate) {
@@ -2100,7 +2098,9 @@
                        } else {
                                analog_play_tone(p, idx, ANALOG_TONE_DIALTONE);
                        }
-                       is_exten_parking = (parking_provider ? 
parking_provider->parking_is_exten_park(ast_channel_context(chan), exten) : 0);
+                       if (ast_parking_provider_registered()) {
+                               is_exten_parking = 
ast_parking_is_exten_park(ast_channel_context(chan), exten);
+                       }
                        if (ast_exists_extension(chan, 
ast_channel_context(chan), exten, 1, p->cid_num) && !is_exten_parking) {
                                if (!res || !ast_matchmore_extension(chan, 
ast_channel_context(chan), exten, 1, p->cid_num)) {
                                        if (getforward) {
@@ -2253,7 +2253,7 @@
                                ast_channel_lock(chan);
                                bridge_channel = 
ast_channel_get_bridge_channel(chan);
                                ast_channel_unlock(chan);
-                               if (bridge_channel && 
!parking_provider->parking_blind_transfer_park(bridge_channel, 
ast_channel_context(chan), exten)) {
+                               if (bridge_channel && 
!ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), 
exten)) {
                                        ast_verb(3, "Parking call to '%s'\n", 
ast_channel_name(chan));
                                }
                                ao2_ref(bridge_channel, -1);

Modified: team/kmoore/parking_unload/include/asterisk/parking.h
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/include/asterisk/parking.h?view=diff&rev=396858&r1=396857&r2=396858
==============================================================================
--- team/kmoore/parking_unload/include/asterisk/parking.h (original)
+++ team/kmoore/parking_unload/include/asterisk/parking.h Fri Aug 16 12:41:20 
2013
@@ -188,25 +188,64 @@
         * \retval non-zero on error
         */
        int (* parking_park_bridge_channel)(struct ast_bridge_channel *parkee, 
const char *parkee_uuid, const char *parker_uuid, const char *app_data);
-
-       /*!
-        * \brief Let the parking provider know it is being used.
-        */
-       void (* parking_ref)(void);
-
-       /*!
-        * \brief Let the parking provider know it is done being used.
-        */
-       void (* parking_unref)(void);
 };
 
 /*!
- * \brief Obtain the current parking provider
- *
- * \retval NULL if no provider exists
- * \retval an ao2 ref counted object of the existing provider's function table
- */
-struct ast_parking_bridge_feature_fn_table 
*ast_parking_get_bridge_features(void);
+ * \brief Determine if the context/exten is a "parking" extension
+ *
+ * \retval 0 if the extension is not a parking extension
+ * \retval 1 if the extension is a parking extension
+ */
+int ast_parking_is_exten_park(const char *context, const char *exten);
+
+/*!
+ * \brief Park the bridge and/or callers that this channel is in
+ *
+ * \param parker The bridge_channel parking the bridge
+ * \param exten Optional. The extension the channel or bridge was parked at if 
the
+ * call succeeds.
+ * \param length Optional. If \c exten is specified, the size of the buffer.
+ *
+ * \note This is safe to be called outside of the \ref AstBridging Bridging 
API.
+ *
+ * \retval 0 on success
+ * \retval non-zero on error
+ */
+int ast_parking_park_call(struct ast_bridge_channel *parker, char *exten, 
size_t length);
+
+/*!
+ * \brief Perform a blind transfer to a parking extension.
+ *
+ * \param parker The \ref bridge_channel object that is initiating the parking
+ * \param context The context to blind transfer to
+ * \param exten The extension to blind transfer to
+ *
+ * \note If the bridge \ref parker is in has more than one other occupant, the 
entire
+ * bridge will be parked using a Local channel
+ *
+ * \note This is safe to be called outside of the \ref AstBridging Bridging 
API.
+ *
+ * \retval 0 on success
+ * \retval non-zero on error
+ */
+int ast_parking_blind_transfer_park(struct ast_bridge_channel *parker, const 
char *context, const char *exten);
+
+/*!
+ * \brief Perform a direct park on a channel in a bridge.
+ *
+ * \param parkee The channel in the bridge to be parked.
+ * \param parkee_uuid The UUID of the channel being packed.
+ * \param parker_uuid The UUID of the channel performing the park.
+ * \param app_data Data to pass to the Park application
+ *
+ * \note This must be called within the context of the \ref AstBridging 
Bridging API.
+ * External entities should not call this method directly, but should instead 
use
+ * the direct call parking method or the blind transfer method.
+ *
+ * \retval 0 on success
+ * \retval non-zero on error
+ */
+int ast_parking_park_bridge_channel(struct ast_bridge_channel *parkee, const 
char *parkee_uuid, const char *parker_uuid, const char *app_data);
 
 /*!
  * \brief Register a parking provider
@@ -227,3 +266,11 @@
  * \retval -1 on error
  */
 int ast_parking_unregister_bridge_features(const char *module_name);
+
+/*!
+ * \brief Check whether a parking provider is registered
+ *
+ * \retval 0 if there is no parking provider regsistered
+ * \retval 1 if there is a parking provider regsistered
+ */
+int ast_parking_provider_registered(void);

Modified: team/kmoore/parking_unload/main/bridge.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/bridge.c?view=diff&rev=396858&r1=396857&r2=396858
==============================================================================
--- team/kmoore/parking_unload/main/bridge.c (original)
+++ team/kmoore/parking_unload/main/bridge.c Fri Aug 16 12:41:20 2013
@@ -3819,11 +3819,8 @@
 static enum ast_transfer_result try_parking(struct ast_channel *transferer, 
const char *context, const char *exten)
 {
        RAII_VAR(struct ast_bridge_channel *, transferer_bridge_channel, NULL, 
ao2_cleanup);
-       RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
-               ast_parking_get_bridge_features(),
-               ao2_cleanup);
-
-       if (!parking_provider) {
+
+       if (!ast_parking_provider_registered()) {
                return AST_BRIDGE_TRANSFER_FAIL;
        }
 
@@ -3835,7 +3832,7 @@
                return AST_BRIDGE_TRANSFER_FAIL;
        }
 
-       if 
(parking_provider->parking_blind_transfer_park(transferer_bridge_channel,
+       if (ast_parking_blind_transfer_park(transferer_bridge_channel,
                context, exten)) {
                return AST_BRIDGE_TRANSFER_FAIL;
        }

Modified: team/kmoore/parking_unload/main/bridge_channel.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/bridge_channel.c?view=diff&rev=396858&r1=396857&r2=396858
==============================================================================
--- team/kmoore/parking_unload/main/bridge_channel.c (original)
+++ team/kmoore/parking_unload/main/bridge_channel.c Fri Aug 16 12:41:20 2013
@@ -757,17 +757,13 @@
  */
 static void bridge_channel_park(struct ast_bridge_channel *bridge_channel, 
struct bridge_park *payload)
 {
-       RAII_VAR(struct ast_parking_bridge_feature_fn_table *, parking_provider,
-               ast_parking_get_bridge_features(),
-               ao2_cleanup);
-
-       if (!parking_provider) {
+       if (!ast_parking_provider_registered()) {
                ast_log(AST_LOG_WARNING, "Unable to park %s: No parking 
provider loaded!\n",
                        ast_channel_name(bridge_channel->chan));
                return;
        }
 
-       if (parking_provider->parking_park_bridge_channel(bridge_channel, 
payload->parkee_uuid,
+       if (ast_parking_park_bridge_channel(bridge_channel, 
payload->parkee_uuid,
                &payload->parkee_uuid[payload->parker_uuid_offset],
                payload->app_data_offset ? 
&payload->parkee_uuid[payload->app_data_offset] : NULL)) {
                ast_log(AST_LOG_WARNING, "Error occurred while parking %s\n",

Modified: team/kmoore/parking_unload/main/parking.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/parking.c?view=diff&rev=396858&r1=396857&r2=396858
==============================================================================
--- team/kmoore/parking_unload/main/parking.c (original)
+++ team/kmoore/parking_unload/main/parking.c Fri Aug 16 12:41:20 2013
@@ -124,41 +124,52 @@
        return payload;
 }
 
-struct parking_provider_wrapper {
-       /*! \brief The actual table that gets accessed */
-       struct ast_parking_bridge_feature_fn_table fn_table;
-       /*! \brief The pointer to the global object from which this table was 
created */
-       struct ast_parking_bridge_feature_fn_table *global;
-};
-
-static void provider_wrapper_dtor(void *obj)
-{
-       struct parking_provider_wrapper *wrapper = obj;
-       if (wrapper->fn_table.parking_unref) {
-               wrapper->fn_table.parking_unref();
-       }
-       ao2_cleanup(wrapper->global);
-       wrapper->global = NULL;
-}
-
-struct ast_parking_bridge_feature_fn_table 
*ast_parking_get_bridge_features(void)
-{
-       RAII_VAR(struct parking_provider_wrapper *, wrapper, 
ao2_alloc(sizeof(*wrapper), provider_wrapper_dtor), ao2_cleanup);
-       if (!wrapper) {
-               return NULL;
-       }
-
-       wrapper->global = ao2_global_obj_ref(parking_provider);
-       if (!wrapper->global) {
-               return NULL;
-       }
-
-       wrapper->fn_table = *wrapper->global;
-       if (wrapper->fn_table.parking_ref) {
-               wrapper->fn_table.parking_ref();
-       }
-       ao2_ref(wrapper, +1);
-       return (struct ast_parking_bridge_feature_fn_table *)wrapper;
+int ast_parking_park_bridge_channel(struct ast_bridge_channel *parkee, const 
char *parkee_uuid, const char *parker_uuid, const char *app_data)
+{
+       RAII_VAR(struct ast_parking_bridge_feature_fn_table *, table,
+               ao2_global_obj_ref(parking_provider), ao2_cleanup);
+       
+       if (!table || !table->parking_park_bridge_channel) {
+               return -1;
+       }
+
+       return table->parking_park_bridge_channel(parkee, parkee_uuid, 
parker_uuid, app_data);
+}
+
+int ast_parking_blind_transfer_park(struct ast_bridge_channel *parker, const 
char *context, const char *exten)
+{
+       RAII_VAR(struct ast_parking_bridge_feature_fn_table *, table,
+               ao2_global_obj_ref(parking_provider), ao2_cleanup);
+       
+       if (!table || !table->parking_blind_transfer_park) {
+               return -1;
+       }
+
+       return table->parking_blind_transfer_park(parker, context, exten);
+}
+
+int ast_parking_park_call(struct ast_bridge_channel *parker, char *exten, 
size_t length)
+{
+       RAII_VAR(struct ast_parking_bridge_feature_fn_table *, table,
+               ao2_global_obj_ref(parking_provider), ao2_cleanup);
+       
+       if (!table || !table->parking_park_call) {
+               return -1;
+       }
+
+       return table->parking_park_call(parker, exten, length);
+}
+
+int ast_parking_is_exten_park(const char *context, const char *exten)
+{
+       RAII_VAR(struct ast_parking_bridge_feature_fn_table *, table,
+               ao2_global_obj_ref(parking_provider), ao2_cleanup);
+       
+       if (!table || !table->parking_is_exten_park) {
+               return -1;
+       }
+
+       return table->parking_is_exten_park(context, exten);
 }
 
 int ast_parking_register_bridge_features(struct 
ast_parking_bridge_feature_fn_table *fn_table)
@@ -206,3 +217,11 @@
        ao2_global_obj_replace_unref(parking_provider, NULL);
        return 0;
 }
+
+int ast_parking_provider_registered(void)
+{
+       RAII_VAR(struct ast_parking_bridge_feature_fn_table *, table,
+               ao2_global_obj_ref(parking_provider), ao2_cleanup);
+       
+       return !!table;
+}

Modified: team/kmoore/parking_unload/res/parking/parking_bridge_features.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/res/parking/parking_bridge_features.c?view=diff&rev=396858&r1=396857&r2=396858
==============================================================================
--- team/kmoore/parking_unload/res/parking/parking_bridge_features.c (original)
+++ team/kmoore/parking_unload/res/parking/parking_bridge_features.c Fri Aug 16 
12:41:20 2013
@@ -40,6 +40,7 @@
 #include "asterisk/say.h"
 #include "asterisk/datastore.h"
 #include "asterisk/stasis.h"
+#include "asterisk/module.h"
 #include "asterisk/core_local.h"
 
 struct parked_subscription_datastore {
@@ -237,6 +238,7 @@
        struct ast_exten *exten_obj;
        struct pbx_find_info info = { .stacklen = 0 }; /* the rest is reset in 
pbx_find_extension */
        const char *app_at_exten;
+       SCOPED_MODULE_USE(parking_get_module());
 
        ast_debug(4, "Checking if %s@%s is a parking exten\n", exten, context);
        exten_obj = pbx_find_extension(NULL, NULL, &info, context, exten, 1, 
NULL, NULL, E_MATCH);
@@ -274,6 +276,7 @@
 {
        RAII_VAR(struct ast_bridge_channel *, other, NULL, ao2_cleanup);
        int peer_count;
+       SCOPED_MODULE_USE(parking_get_module());
 
        if (ast_strlen_zero(context) || ast_strlen_zero(exten)) {
                return -1;
@@ -350,6 +353,7 @@
        RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
        RAII_VAR(struct ast_bridge *, original_bridge, NULL, ao2_cleanup);
        RAII_VAR(struct ast_channel *, parker, NULL, ao2_cleanup);
+       SCOPED_MODULE_USE(parking_get_module());
 
        if (strcmp(ast_channel_uniqueid(bridge_channel->chan), uuid_parkee)) {
                /* We aren't the parkee, so ignore this action. */
@@ -414,6 +418,7 @@
 {
        RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
        const char *lot_name = NULL;
+       SCOPED_MODULE_USE(parking_get_module());
 
        ast_channel_lock(parker->chan);
        lot_name = find_channel_parking_lot_name(parker->chan);
@@ -442,10 +447,9 @@
 static int feature_park_call(struct ast_bridge_channel *bridge_channel, void 
*hook_pvt)
 {
        int res;
-
-       parking_ref();
+       SCOPED_MODULE_USE(parking_get_module());
+
        res = parking_park_call(bridge_channel, NULL, 0);
-       parking_unref();
 
        return res;
 }
@@ -616,8 +620,6 @@
        .parking_blind_transfer_park = parking_blind_transfer_park,
        .parking_park_bridge_channel = parking_park_bridge_channel,
        .parking_park_call = parking_park_call,
-       .parking_ref = parking_ref,
-       .parking_unref = parking_unref,
 };
 
 void unload_parking_bridge_features(void)

Modified: team/kmoore/parking_unload/res/parking/res_parking.h
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/res/parking/res_parking.h?view=diff&rev=396858&r1=396857&r2=396858
==============================================================================
--- team/kmoore/parking_unload/res/parking/res_parking.h (original)
+++ team/kmoore/parking_unload/res/parking/res_parking.h Fri Aug 16 12:41:20 
2013
@@ -554,12 +554,8 @@
 
 /*!
  * \since 12.0.0
- * \brief Increment res_parking's use count
- */
-void parking_ref(void);
-
-/*!
- * \since 12.0.0
- * \brief Decrement res_parking's use count
- */
-void parking_unref(void);
+ * \brief Get res_parking's module for module ref counting purposes
+ *
+ * \retval res_parking's ast_module
+ */
+struct ast_module *parking_get_module(void);

Modified: team/kmoore/parking_unload/res/res_parking.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/res/res_parking.c?view=diff&rev=396858&r1=396857&r2=396858
==============================================================================
--- team/kmoore/parking_unload/res/res_parking.c (original)
+++ team/kmoore/parking_unload/res/res_parking.c Fri Aug 16 12:41:20 2013
@@ -33,6 +33,9 @@
                <configFile name="res_parking.conf">
                        <configObject name="globals">
                                <synopsis>Options that apply to every parking 
lot</synopsis>
+                               <configOption name="parkeddynamic">
+                                       <synopsis>Enables dynamically created 
parkinglots.</synopsis>
+                               </configOption>
                        </configObject>
                        <configObject name="parking_lot">
                                <synopsis>Defined parking lots for res_parking 
to use to park calls on</synopsis>
@@ -1152,14 +1155,9 @@
        disable_marked_lots();
 }
 
-void parking_ref(void)
-{
-       ast_module_ref(ast_module_info->self);
-}
-
-void parking_unref(void)
-{
-       ast_module_unref(ast_module_info->self);
+struct ast_module *parking_get_module(void)
+{
+       return ast_module_info->self;
 }
 
 static int unload_module(void)


--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to