static struct ast_vector_string startup_errors;
static struct ast_str *startup_error_builder;
-#if defined(HAVE_PERMANENT_DLOPEN)
-#define FIRST_DLOPEN 999
-
-struct ao2_container *info_list = NULL;
-
-struct info_list_obj {
- const struct ast_module_info *info;
- int dlopened;
- char name[0];
-};
-
-static struct info_list_obj *info_list_obj_alloc(const char *name,
- const struct ast_module_info *info)
-{
- struct info_list_obj *new_entry;
-
- new_entry = ao2_alloc(sizeof(*new_entry) + strlen(name) + 1, NULL);
-
- if (!new_entry) {
- return NULL;
- }
-
- strcpy(new_entry->name, name); /* SAFE */
- new_entry->info = info;
- new_entry->dlopened = FIRST_DLOPEN;
-
- return new_entry;
-}
-
-AO2_STRING_FIELD_CMP_FN(info_list_obj, name)
-
+#if defined(HAVE_PERMANENT_DLOPEN) || defined(AST_XML_DOCS)
static char *get_name_from_resource(const char *resource)
{
int len;
/* Unable to allocate memory. */
return NULL;
}
+#endif
+
+#if defined(HAVE_PERMANENT_DLOPEN)
+#define FIRST_DLOPEN 999
+
+struct ao2_container *info_list = NULL;
+
+struct info_list_obj {
+ const struct ast_module_info *info;
+ int dlopened;
+ char name[0];
+};
+
+static struct info_list_obj *info_list_obj_alloc(const char *name,
+ const struct ast_module_info *info)
+{
+ struct info_list_obj *new_entry;
+
+ new_entry = ao2_alloc(sizeof(*new_entry) + strlen(name) + 1, NULL);
+
+ if (!new_entry) {
+ return NULL;
+ }
+
+ strcpy(new_entry->name, name); /* SAFE */
+ new_entry->info = info;
+ new_entry->dlopened = FIRST_DLOPEN;
+
+ return new_entry;
+}
+
+AO2_STRING_FIELD_CMP_FN(info_list_obj, name)
static void manual_mod_reg(const void *lib, const char *resource)
{
int res = 0;
int modulecount = 0;
int i;
+ struct ast_module *cur;
+#ifdef AST_XML_DOCS
+ struct ast_str *warning_msg;
+ char deprecated_in[33];
+ char removed_in[33];
+ char replacement[129];
+#endif
+ struct timeval start_time = ast_tvnow();
+ struct timeval end_time;
+ int64_t usElapsed;
ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
ast_free(order);
}
+#ifdef AST_XML_DOCS
+ warning_msg = ast_str_create(512);
+#endif
+
+ AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
+#ifdef AST_XML_DOCS
+ char *mod_name = NULL;
+ struct ast_xml_xpath_results *results;
+#endif
+
+ if (!cur->flags.running || cur->flags.declined) {
+ continue;
+ }
+
+#ifdef AST_XML_DOCS
+ mod_name = get_name_from_resource(cur->resource);
+ if (!warning_msg || !mod_name) {
+ /* If we can't allocate memory, we have bigger issues */
+ ast_free(mod_name);
+ continue;
+ }
+
+ results = ast_xmldoc_query("/docs/module[@name='%s']/deprecated_in", mod_name);
+ deprecated_in[0] = '\0';
+ if (results) {
+ const char *result_tmp = ast_xml_get_text(ast_xml_xpath_get_first_result(results));
+ if (!ast_strlen_zero(result_tmp)) {
+ ast_copy_string(deprecated_in, result_tmp, sizeof(deprecated_in));
+ }
+ ast_xml_xpath_results_free(results);
+ }
+
+ results = ast_xmldoc_query("/docs/module[@name='%s']/removed_in", mod_name);
+ removed_in[0] = '\0';
+ if (results) {
+ const char *result_tmp = ast_xml_get_text(ast_xml_xpath_get_first_result(results));
+ if (!ast_strlen_zero(result_tmp)) {
+ ast_copy_string(removed_in, result_tmp, sizeof(removed_in));
+ }
+ ast_xml_xpath_results_free(results);
+ }
+
+ results = ast_xmldoc_query("/docs/module[@name='%s']/replacement", mod_name);
+ replacement[0] = '\0';
+ if (results) {
+ const char *result_tmp = ast_xml_get_text(ast_xml_xpath_get_first_result(results));
+ if (!ast_strlen_zero(result_tmp)) {
+ ast_copy_string(replacement, result_tmp, sizeof(replacement));
+ }
+ ast_xml_xpath_results_free(results);
+ }
+
+ ast_str_reset(warning_msg);
+
+ if (cur->info->support_level == AST_MODULE_SUPPORT_DEPRECATED || !ast_strlen_zero(deprecated_in)
+ || !ast_strlen_zero(removed_in) || !ast_strlen_zero(replacement)) {
+ int already_butted = 0;
+
+ ast_str_append(&warning_msg, -1, "Module '%s' has been loaded", mod_name);
+ if (!ast_strlen_zero(deprecated_in)) {
+ ast_str_append(&warning_msg, -1, " but %s deprecated in Asterisk version %s",
+ cur->info->support_level == AST_MODULE_SUPPORT_DEPRECATED ? "was" : "will be", deprecated_in);
+ already_butted = 1;
+ }
+
+ if (!ast_strlen_zero(removed_in)) {
+ ast_str_append(&warning_msg, -1, " %s will be removed in Asterisk version %s", already_butted ? "and" : "but", removed_in);
+ } else {
+ ast_str_append(&warning_msg, -1, " %s may be removed in a future release", already_butted ? "and" : "but");
+ }
+
+ ast_str_append(&warning_msg, -1, ".");
+
+ if (!ast_strlen_zero(replacement)) {
+ ast_str_append(&warning_msg, -1, " Its replacement is '%s'.", replacement);
+ }
+ }
+
+ if (ast_str_strlen(warning_msg)) {
+ ast_log(LOG_WARNING, "%s\n", ast_str_buffer(warning_msg));
+ }
+
+ ast_free(mod_name);
+#else
+ if (cur->info->support_level == AST_MODULE_SUPPORT_DEPRECATED) {
+ ast_log(LOG_WARNING, "The deprecated module '%s' has been loaded and is running, it may be removed in a future version\n", cur->resource);
+ }
+#endif
+ }
+
+#ifdef AST_XML_DOCS
+ ast_free(warning_msg);
+#endif
+
AST_DLLIST_UNLOCK(&module_list);
+
for (i = 0; i < AST_VECTOR_SIZE(&startup_errors); i++) {
char *str = AST_VECTOR_GET(&startup_errors, i);
ast_free(startup_error_builder);
startup_error_builder = NULL;
+ end_time = ast_tvnow();
+ usElapsed = ast_tvdiff_us(end_time, start_time);
+
+#ifdef AST_XML_DOCS
+ ast_debug(1, "Loader time with AST_XML_DOCS: %ld.%06ld\n", usElapsed / 1000000, usElapsed % 1000000);
+#else
+ ast_debug(1, "Loader time without AST_XML_DOCS: %ld.%06ld\n", usElapsed / 1000000, usElapsed % 1000000);
+#endif
+
return res;
}