Temporary fix for people using sample features.conf from previous Asterisk versions.
[asterisk/asterisk.git] / main / features_config.c
index f8bdb1c..163c37d 100644 (file)
@@ -281,7 +281,7 @@ static void *featuregroup_alloc(const char *cat)
        }
 
        group->items = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK,
-                       AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, group_item_sort, NULL);
+               AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, group_item_sort, NULL);
        if (!group->items) {
                ao2_cleanup(group);
                return NULL;
@@ -418,10 +418,11 @@ static struct features_global_config *global_config_alloc(void)
        return cfg;
 }
 
-static struct ao2_container *applicationmap_alloc(void)
+static struct ao2_container *applicationmap_alloc(int replace_duplicates)
 {
        return ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK,
-                       AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, applicationmap_sort, NULL);
+               replace_duplicates ? AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE : AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW,
+               applicationmap_sort, NULL);
 }
 
 /*!
@@ -457,7 +458,7 @@ static struct features_config *__features_config_alloc(int allocate_applicationm
        }
 
        if (allocate_applicationmap) {
-               cfg->applicationmap = applicationmap_alloc();
+               cfg->applicationmap = applicationmap_alloc(1);
                if (!cfg->applicationmap) {
                        return NULL;
                }
@@ -901,13 +902,13 @@ int ast_get_feature(struct ast_channel *chan, const char *feature, char *buf, si
 {
        RAII_VAR(struct ao2_container *, applicationmap, NULL, ao2_cleanup);
        RAII_VAR(struct ast_applicationmap_item *, item, NULL, ao2_cleanup);
+
        if (!ast_get_builtin_feature(chan, feature, buf, len)) {
                return 0;
        }
 
        /* Dang, must be in the application map */
        applicationmap = ast_get_chan_applicationmap(chan);
-
        if (!applicationmap) {
                return -1;
        }
@@ -968,10 +969,7 @@ static int add_item(void *obj, void *arg, int flags)
                return 0;
        }
 
-       if (!ao2_link(applicationmap, appmap_item)) {
-               ast_log(LOG_WARNING, "Unable to add applicationmap item %s. Possible duplicate\n",
-                               fg_item->appmap_item_name);
-       }
+       ao2_link(applicationmap, appmap_item);
        return 0;
 }
 
@@ -999,17 +997,22 @@ struct ao2_container *ast_get_chan_applicationmap(struct ast_channel *chan)
                return NULL;
        }
 
-       applicationmap = applicationmap_alloc();
+       applicationmap = applicationmap_alloc(0);
        if (!applicationmap) {
                return NULL;
        }
 
        while ((name = strsep(&group_names, "#"))) {
                RAII_VAR(struct featuregroup *, group, ao2_find(cfg->featuregroups, name, OBJ_KEY), ao2_cleanup);
+
                if (!group) {
                        RAII_VAR(struct ast_applicationmap_item *, item, ao2_find(cfg->applicationmap, name, OBJ_KEY), ao2_cleanup);
-                       if (item && !ao2_link(applicationmap, item)) {
-                               ast_log(LOG_WARNING, "Unable to add applicationmap item %s. Possible duplicate.\n", item->name);
+
+                       if (item) {
+                               ao2_link(applicationmap, item);
+                       } else {
+                               ast_log(LOG_WARNING, "Unknown DYNAMIC_FEATURES item '%s' on channel %s.\n",
+                                       name, ast_channel_name(chan));
                        }
                } else {
                        ao2_callback(group->items, 0, add_item, applicationmap);
@@ -1109,7 +1112,7 @@ static int applicationmap_handler(const struct aco_option *opt,
        }
 
        if (!ao2_link(applicationmap, item)) {
-               ast_log(LOG_WARNING, "Unable to add applicationmap item %s. Possible duplicate\n", item->name);
+               return -1;
        }
 
        return 0;
@@ -1130,7 +1133,7 @@ static int featuregroup_handler(const struct aco_option *opt,
        ast_string_field_set(item, dtmf_override, var->value);
 
        if (!ao2_link(group->items, item)) {
-               ast_log(LOG_WARNING, "Unable to add featuregroup item %s. Possible duplicate\n", item->appmap_item_name);
+               return -1;
        }
 
        /* We wait to look up the application map item in the preapply callback */
@@ -1165,6 +1168,13 @@ static int pickup_handler(const struct aco_option *opt,
        return pickup_set(pickup, var->name, var->value);
 }
 
+static int unsupported_handler(const struct aco_option *opt,
+               struct ast_variable *var, void *obj)
+{
+       ast_log(LOG_WARNING, "The option '%s' is no longer configurable in features.conf.\n", var->name);
+       return 0;
+}
+
 static int featuremap_handler(const struct aco_option *opt,
                struct ast_variable *var, void *obj)
 {
@@ -1375,6 +1385,41 @@ static int load_config(int reload)
        aco_option_register_custom(&cfg_info, "pickupfailsound", ACO_EXACT, global_options,
                        DEFAULT_PICKUPFAILSOUND, pickup_handler, 0);
 
+       aco_option_register_custom(&cfg_info, "context", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkext", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkext_exclusive", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkinghints", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkedmusicclass", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkingtime", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkpos", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "findslot", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkedcalltransfers", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkedcallreparking", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkedcallhangup", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkedcallrecording", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "comebackcontext", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "comebacktoorigin", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "comebackdialtime", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "parkeddynamic", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+       aco_option_register_custom(&cfg_info, "adsipark", ACO_EXACT, global_options,
+                       "", unsupported_handler, 0);
+
        aco_option_register_custom(&cfg_info, "blindxfer", ACO_EXACT, featuremap_options,
                        DEFAULT_FEATUREMAP_BLINDXFER, featuremap_handler, 0);
        aco_option_register_custom(&cfg_info, "disconnect", ACO_EXACT, featuremap_options,