[asterisk-commits] irroot: branch irroot/distrotech-customers-10 r334417 - in /team/irroot/distr...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Sep 3 04:20:30 CDT 2011


Author: irroot
Date: Sat Sep  3 04:20:19 2011
New Revision: 334417

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=334417
Log:
Initialized merge tracking via "svnmerge" with revisions "1-333477" from 
https://origsvn.digium.com/svn/asterisk/branches/10

Modified:
    team/irroot/distrotech-customers-10/   (props changed)
    team/irroot/distrotech-customers-10/CHANGES
    team/irroot/distrotech-customers-10/include/asterisk/config.h
    team/irroot/distrotech-customers-10/main/config.c
    team/irroot/distrotech-customers-10/main/pbx.c
    team/irroot/distrotech-customers-10/res/res_config_odbc.c
    team/irroot/distrotech-customers-10/res/res_musiconhold.c

Propchange: team/irroot/distrotech-customers-10/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/irroot/distrotech-customers-10/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Propchange: team/irroot/distrotech-customers-10/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Sep  3 04:20:19 2011
@@ -1,1 +1,1 @@
-/branches/10:333478-334215
+/branches/10:333478-334416

Propchange: team/irroot/distrotech-customers-10/
------------------------------------------------------------------------------
    svnmerge-integrated = /branches/10:1-333477

Modified: team/irroot/distrotech-customers-10/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-10/CHANGES?view=diff&rev=334417&r1=334416&r2=334417
==============================================================================
--- team/irroot/distrotech-customers-10/CHANGES (original)
+++ team/irroot/distrotech-customers-10/CHANGES Sat Sep  3 04:20:19 2011
@@ -174,7 +174,7 @@
 --------------------------
  * The ReceiveFAXStatus and SendFAXStatus manager events have been consolidated
    into a FAXStatus event with an 'Operation' header that will be either
-   'send', 'receive', and 'gateway'.
+   'send', 'receive', or 'gateway'.
  * T.38 gateway functionality has been added to res_fax (and res_fax_spandsp).
    Set FAXOPT(gateway)=yes to enable this functionality on a channel. This
    feature will handle converting a fax call between an audio T.30 fax terminal

Modified: team/irroot/distrotech-customers-10/include/asterisk/config.h
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-10/include/asterisk/config.h?view=diff&rev=334417&r1=334416&r2=334417
==============================================================================
--- team/irroot/distrotech-customers-10/include/asterisk/config.h (original)
+++ team/irroot/distrotech-customers-10/include/asterisk/config.h Sat Sep  3 04:20:19 2011
@@ -73,11 +73,16 @@
 
 /*! \brief Structure for variables, used for configurations and for channel variables */
 struct ast_variable {
+	/*! Variable name.  Stored in stuff[] at struct end. */
 	const char *name;
+	/*! Variable value.  Stored in stuff[] at struct end. */
 	const char *value;
+
+	/*! Next node in the list. */
 	struct ast_variable *next;
 
-	char *file;
+	/*! Filename where variable found.  Stored in stuff[] at struct end. */
+	const char *file;
 
 	int lineno;
 	int object;		/*!< 0 for variable, 1 for object */
@@ -85,6 +90,10 @@
 	struct ast_comment *precomments;
 	struct ast_comment *sameline;
 	struct ast_comment *trailing; /*!< the last object in the list will get assigned any trailing comments when EOF is hit */
+	/*!
+	 * \brief Contents of file, name, and value in that order stuffed here.
+	 * \note File must be stuffed before name because of ast_include_rename().
+	 */
 	char stuff[0];
 };
 

Modified: team/irroot/distrotech-customers-10/main/config.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-10/main/config.c?view=diff&rev=334417&r1=334416&r2=334417
==============================================================================
--- team/irroot/distrotech-customers-10/main/config.c (original)
+++ team/irroot/distrotech-customers-10/main/config.c Sat Sep  3 04:20:19 2011
@@ -55,12 +55,20 @@
 #define COMMENT_META ';'
 #define COMMENT_TAG '-'
 
+/*!
+ * Define the minimum filename space to reserve for each
+ * ast_variable in case the filename is renamed later by
+ * ast_include_rename().
+ */
+#define MIN_VARIABLE_FNAME_SPACE	40
+
 static char *extconfig_conf = "extconfig.conf";
 
 
 /*! \brief Structure to keep comments for rewriting configuration files */
 struct ast_comment {
 	struct ast_comment *next;
+	/*! Comment body allocated after struct. */
 	char cmt[0];
 };
 
@@ -72,13 +80,17 @@
 
 struct cache_file_mtime {
 	AST_LIST_ENTRY(cache_file_mtime) list;
-	AST_LIST_HEAD(includes, cache_file_include) includes;
+	AST_LIST_HEAD_NOLOCK(includes, cache_file_include) includes;
 	unsigned int has_exec:1;
 	time_t mtime;
-	char *who_asked;
+
+	/*! String stuffed in filename[] after the filename string. */
+	const char *who_asked;
+	/*! Filename and who_asked stuffed after it. */
 	char filename[0];
 };
 
+/*! Cached file mtime list. */
 static AST_LIST_HEAD_STATIC(cfmtime_head, cache_file_mtime);
 
 static int init_appendbuf(void *data)
@@ -164,10 +176,15 @@
 static struct ast_config_map {
 	struct ast_config_map *next;
 	int priority;
-	char *name;
-	char *driver;
-	char *database;
-	char *table;
+	/*! Stored in stuff[] at struct end. */
+	const char *name;
+	/*! Stored in stuff[] at struct end. */
+	const char *driver;
+	/*! Stored in stuff[] at struct end. */
+	const char *database;
+	/*! Stored in stuff[] at struct end. */
+	const char *table;
+	/*! Contents of name, driver, database, and table in that order stuffed here. */
 	char stuff[0];
 } *config_maps = NULL;
 
@@ -186,19 +203,28 @@
 	char name[80];
 	int ignored;			/*!< do not let user of the config see this category -- set by (!) after the category decl; a template */
 	int include_level;
-	char *file;	           /*!< the file name from whence this declaration was read */
+	/*!
+	 * \brief The file name from whence this declaration was read
+	 * \note Will never be NULL
+	 */
+	char *file;
 	int lineno;
 	AST_LIST_HEAD_NOLOCK(template_instance_list, ast_category_template_instance) template_instances;
 	struct ast_comment *precomments;
 	struct ast_comment *sameline;
 	struct ast_comment *trailing; /*!< the last object in the list will get assigned any trailing comments when EOF is hit */
+	/*! First category variable in the list. */
 	struct ast_variable *root;
+	/*! Last category variable in the list. */
 	struct ast_variable *last;
+	/*! Next node in the list. */
 	struct ast_category *next;
 };
 
 struct ast_config {
+	/*! First config category in the list. */
 	struct ast_category *root;
+	/*! Last config category in the list. */
 	struct ast_category *last;
 	struct ast_category *current;
 	struct ast_category *last_browse;     /*!< used to cache the last category supplied via category_browse */
@@ -208,41 +234,87 @@
 };
 
 struct ast_config_include {
-	char *include_location_file;     /*!< file name in which the include occurs */
+	/*!
+	 * \brief file name in which the include occurs
+	 * \note Will never be NULL
+	 */
+	char *include_location_file;
 	int  include_location_lineno;    /*!< lineno where include occurred */
-	int  exec;                       /*!< set to non-zero if itsa #exec statement */
-	char *exec_file;                 /*!< if it's an exec, you'll have both the /var/tmp to read, and the original script */
-	char *included_file;             /*!< file name included */
+	int  exec;                       /*!< set to non-zero if its a #exec statement */
+	/*!
+	 * \brief if it's an exec, you'll have both the /var/tmp to read, and the original script
+	 * \note Will never be NULL if exec is non-zero
+	 */
+	char *exec_file;
+	/*!
+	 * \brief file name included
+	 * \note Will never be NULL
+	 */
+	char *included_file;
 	int inclusion_count;             /*!< if the file is included more than once, a running count thereof -- but, worry not,
 	                                      we explode the instances and will include those-- so all entries will be unique */
 	int output;                      /*!< a flag to indicate if the inclusion has been output */
 	struct ast_config_include *next; /*!< ptr to next inclusion in the list */
 };
 
+static void ast_variable_destroy(struct ast_variable *doomed);
+static void ast_includes_destroy(struct ast_config_include *incls);
+
 #ifdef MALLOC_DEBUG
-struct ast_variable *_ast_variable_new(const char *name, const char *value, const char *filename, const char *file, const char *func, int lineno) 
+struct ast_variable *_ast_variable_new(const char *name, const char *value, const char *filename, const char *file, const char *func, int lineno)
 #else
-struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename) 
+struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename)
 #endif
 {
 	struct ast_variable *variable;
-	int name_len = strlen(name) + 1;	
-	int val_len = strlen(value) + 1;	
-	int fn_len = strlen(filename) + 1;	
-
+	int name_len = strlen(name) + 1;
+	int val_len = strlen(value) + 1;
+	int fn_len = strlen(filename) + 1;
+
+	/* Ensure a minimum length in case the filename is changed later. */
+	if (fn_len < MIN_VARIABLE_FNAME_SPACE) {
+		fn_len = MIN_VARIABLE_FNAME_SPACE;
+	}
+
+	if (
 #ifdef MALLOC_DEBUG
-	if ((variable = __ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable), file, lineno, func))) {
+		(variable = __ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable), file, lineno, func))
 #else
-	if ((variable = ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable)))) {
+		(variable = ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable)))
 #endif
+		) {
 		char *dst = variable->stuff;	/* writable space starts here */
+
+		/* Put file first so ast_include_rename() can calculate space available. */
+		variable->file = strcpy(dst, filename);
+		dst += fn_len;
 		variable->name = strcpy(dst, name);
 		dst += name_len;
 		variable->value = strcpy(dst, value);
-		dst += val_len;
-		variable->file = strcpy(dst, filename);
 	}
 	return variable;
+}
+
+/*!
+ * \internal
+ * \brief Move the contents from the source to the destination variable.
+ *
+ * \param dst_var Destination variable node
+ * \param src_var Source variable node
+ *
+ * \return Nothing
+ */
+static void ast_variable_move(struct ast_variable *dst_var, struct ast_variable *src_var)
+{
+	dst_var->lineno = src_var->lineno;
+	dst_var->object = src_var->object;
+	dst_var->blanklines = src_var->blanklines;
+	dst_var->precomments = src_var->precomments;
+	src_var->precomments = NULL;
+	dst_var->sameline = src_var->sameline;
+	src_var->sameline = NULL;
+	dst_var->trailing = src_var->trailing;
+	src_var->trailing = NULL;
 }
 
 struct ast_config_include *ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size)
@@ -265,6 +337,9 @@
 		*real_included_file_name = 0;
 	
 	inc = ast_calloc(1,sizeof(struct ast_config_include));
+	if (!inc) {
+		return NULL;
+	}
 	inc->include_location_file = ast_strdup(from_file);
 	inc->include_location_lineno = from_lineno;
 	if (!ast_strlen_zero(real_included_file_name))
@@ -275,7 +350,14 @@
 	inc->exec = is_exec;
 	if (is_exec)
 		inc->exec_file = ast_strdup(exec_file);
-	
+
+	if (!inc->include_location_file
+		|| !inc->included_file
+		|| (is_exec && !inc->exec_file)) {
+		ast_includes_destroy(inc);
+		return NULL;
+	}
+
 	/* attach this new struct to the conf struct */
 	inc->next = conf->includes;
 	conf->includes = inc;
@@ -287,8 +369,8 @@
 {
 	struct ast_config_include *incl;
 	struct ast_category *cat;
-	struct ast_variable *v;
-	
+	char *str;
+
 	int from_len = strlen(from_file);
 	int to_len = strlen(to_file);
 	
@@ -309,29 +391,68 @@
 			if (from_len >= to_len)
 				strcpy(incl->include_location_file, to_file);
 			else {
-				free(incl->include_location_file);
-				incl->include_location_file = strdup(to_file);
+				/* Keep the old filename if the allocation fails. */
+				str = ast_strdup(to_file);
+				if (str) {
+					ast_free(incl->include_location_file);
+					incl->include_location_file = str;
+				}
 			}
 		}
 	}
 	for (cat = conf->root; cat; cat = cat->next) {
+		struct ast_variable **prev;
+		struct ast_variable *v;
+		struct ast_variable *new_var;
+
 		if (strcmp(cat->file,from_file) == 0) {
 			if (from_len >= to_len)
 				strcpy(cat->file, to_file);
 			else {
-				free(cat->file);
-				cat->file = strdup(to_file);
-			}
-		}
-		for (v = cat->root; v; v = v->next) {
-			if (strcmp(v->file,from_file) == 0) {
-				if (from_len >= to_len)
-					strcpy(v->file, to_file);
-				else {
-					free(v->file);
-					v->file = strdup(to_file);
-				}
-			}
+				/* Keep the old filename if the allocation fails. */
+				str = ast_strdup(to_file);
+				if (str) {
+					ast_free(cat->file);
+					cat->file = str;
+				}
+			}
+		}
+		for (prev = &cat->root, v = cat->root; v; prev = &v->next, v = v->next) {
+			if (strcmp(v->file, from_file)) {
+				continue;
+			}
+
+			/*
+			 * Calculate actual space available.  The file string is
+			 * intentionally stuffed before the name string just so we can
+			 * do this.
+			 */
+			if (to_len < v->name - v->file) {
+				/* The new name will fit in the available space. */
+				str = (char *) v->file;/* Stupid compiler complains about discarding qualifiers even though I used a cast. */
+				strcpy(str, to_file);/* SAFE */
+				continue;
+			}
+
+			/* Keep the old filename if the allocation fails. */
+			new_var = ast_variable_new(v->name, v->value, to_file);
+			if (!new_var) {
+				continue;
+			}
+
+			/* Move items from the old list node to the replacement node. */
+			ast_variable_move(new_var, v);
+
+			/* Replace the old node in the list with the new node. */
+			new_var->next = v->next;
+			if (cat->last == v) {
+				cat->last = new_var;
+			}
+			*prev = new_var;
+
+			ast_variable_destroy(v);
+
+			v = new_var;
 		}
 	}
 }
@@ -491,9 +612,16 @@
 {
 	struct ast_category *category;
 
-	if ((category = ast_calloc(1, sizeof(*category))))
-		ast_copy_string(category->name, name, sizeof(category->name));
-	category->file = strdup(in_file);
+	category = ast_calloc(1, sizeof(*category));
+	if (!category) {
+		return NULL;
+	}
+	category->file = ast_strdup(in_file);
+	if (!category->file) {
+		ast_category_destroy(category);
+		return NULL;
+	}
+	ast_copy_string(category->name, name, sizeof(category->name));
 	category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
 	return category;
 }
@@ -562,20 +690,19 @@
 	struct ast_category_template_instance *x;
 
 	while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next)))
-		free(x);
+		ast_free(x);
 }
 
 void ast_category_destroy(struct ast_category *cat)
 {
 	ast_variables_destroy(cat->root);
-	if (cat->file) {
-		free(cat->file);
-		cat->file = 0;
-	}
+	cat->root = NULL;
+	cat->last = NULL;
 	ast_comment_destroy(&cat->precomments);
 	ast_comment_destroy(&cat->sameline);
 	ast_comment_destroy(&cat->trailing);
 	ast_destroy_template_list(cat);
+	ast_free(cat->file);
 	ast_free(cat);
 }
 
@@ -585,13 +712,10 @@
 	
 	for (incl=incls; incl; incl = inclnext) {
 		inclnext = incl->next;
-		if (incl->include_location_file)
-			free(incl->include_location_file);
-		if (incl->exec_file)
-			free(incl->exec_file);
-		if (incl->included_file)
-			free(incl->included_file);
-		free(incl);
+		ast_free(incl->include_location_file);
+		ast_free(incl->exec_file);
+		ast_free(incl->included_file);
+		ast_free(incl);
 	}
 }
 
@@ -682,8 +806,12 @@
 static void inherit_category(struct ast_category *new, const struct ast_category *base)
 {
 	struct ast_variable *var;
-	struct ast_category_template_instance *x = ast_calloc(1,sizeof(struct ast_category_template_instance));
-
+	struct ast_category_template_instance *x;
+
+	x = ast_calloc(1, sizeof(*x));
+	if (!x) {
+		return;
+	}
 	strcpy(x->name, base->name);
 	x->inst = base;
 	AST_LIST_INSERT_TAIL(&new->template_instances, x, next);
@@ -757,17 +885,12 @@
 
 		if (!(newer = ast_variable_new(variable, value, cur->file)))
 			return -1;
-	
+
+		ast_variable_move(newer, cur);
+		newer->object = newer->object || object;
+
+		/* Replace the old node in the list with the new node. */
 		newer->next = cur->next;
-		newer->object = cur->object || object;
-
-		/* Preserve everything */
-		newer->lineno = cur->lineno;
-		newer->blanklines = cur->blanklines;
-		newer->precomments = cur->precomments; cur->precomments = NULL;
-		newer->sameline = cur->sameline; cur->sameline = NULL;
-		newer->trailing = cur->trailing; cur->trailing = NULL;
-
 		if (prev)
 			prev->next = newer;
 		else
@@ -775,8 +898,7 @@
 		if (category->last == cur)
 			category->last = newer;
 
-		cur->next = NULL;
-		ast_variables_destroy(cur);
+		ast_variable_destroy(cur);
 
 		return 0;
 	}
@@ -875,6 +997,34 @@
 	cfg->current = (struct ast_category *) cat;
 }
 
+/*!
+ * \internal
+ * \brief Create a new cfmtime list node.
+ *
+ * \param filename Config filename caching.
+ * \param who_asked Who wanted to know.
+ *
+ * \retval cfmtime New node on success.
+ * \retval NULL on error.
+ */
+static struct cache_file_mtime *cfmtime_new(const char *filename, const char *who_asked)
+{
+	struct cache_file_mtime *cfmtime;
+	char *dst;
+
+	cfmtime = ast_calloc(1,
+		sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
+	if (!cfmtime) {
+		return NULL;
+	}
+	dst = cfmtime->filename;	/* writable space starts here */
+	strcpy(dst, filename);
+	dst += strlen(dst) + 1;
+	cfmtime->who_asked = strcpy(dst, who_asked);
+
+	return cfmtime;
+}
+
 enum config_cache_attribute_enum {
 	ATTRIBUTE_INCLUDE = 0,
 	ATTRIBUTE_EXEC = 1,
@@ -893,15 +1043,11 @@
 			break;
 	}
 	if (!cfmtime) {
-		cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(configfile) + 1 + strlen(who_asked) + 1);
+		cfmtime = cfmtime_new(configfile, who_asked);
 		if (!cfmtime) {
 			AST_LIST_UNLOCK(&cfmtime_head);
 			return;
 		}
-		AST_LIST_HEAD_INIT(&cfmtime->includes);
-		strcpy(cfmtime->filename, configfile);
-		cfmtime->who_asked = cfmtime->filename + strlen(configfile) + 1;
-		strcpy(cfmtime->who_asked, who_asked);
 		/* Note that the file mtime is initialized to 0, i.e. 1970 */
 		AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
 	}
@@ -1226,8 +1372,7 @@
 		if (comment_buffer)
 			lline_buffer = ast_str_create(CB_SIZE);
 		if (!lline_buffer) {
-			if (comment_buffer)
-				ast_free(comment_buffer);
+			ast_free(comment_buffer);
 			ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n");
 			return NULL;
 		}
@@ -1272,13 +1417,9 @@
 					break;
 			}
 			if (!cfmtime) {
-				cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(fn) + 1 + strlen(who_asked) + 1);
+				cfmtime = cfmtime_new(fn, who_asked);
 				if (!cfmtime)
 					continue;
-				AST_LIST_HEAD_INIT(&cfmtime->includes);
-				strcpy(cfmtime->filename, fn);
-				cfmtime->who_asked = cfmtime->filename + strlen(fn) + 1;
-				strcpy(cfmtime->who_asked, who_asked);
 				/* Note that the file mtime is initialized to 0, i.e. 1970 */
 				AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
 			}
@@ -1327,8 +1468,11 @@
 			AST_LIST_UNLOCK(&cfmtime_head);
 
 		/* If cfg is NULL, then we just want an answer */
-		if (cfg == NULL)
+		if (cfg == NULL) {
+			ast_free(comment_buffer);
+			ast_free(lline_buffer);
 			return NULL;
+		}
 
 		if (cfmtime)
 			cfmtime->mtime = statbuf.st_mtime;
@@ -1470,10 +1614,8 @@
 #endif
 
 	if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID && cfg->include_level == 1 && ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
-		if (comment_buffer)
-			ast_free(comment_buffer);
-		if (lline_buffer)
-			ast_free(lline_buffer);
+		ast_free(comment_buffer);
+		ast_free(lline_buffer);
 		comment_buffer = NULL;
 		lline_buffer = NULL;
 	}
@@ -1524,38 +1666,52 @@
 	fprintf(f1, ";!\n");
 }
 
-static void   inclfile_destroy(void *obj)
+static void inclfile_destroy(void *obj)
 {
 	const struct inclfile *o = obj;
 
-	if (o->fname)
-		free(o->fname);
-}
-
-
-static void set_fn(char *fn, int fn_size, const char *file, const char *configfile, struct ao2_container *fileset, struct inclfile **fi)
+	ast_free(o->fname);
+}
+
+
+static struct inclfile *set_fn(char *fn, int fn_size, const char *file, const char *configfile, struct ao2_container *fileset)
 {
 	struct inclfile lookup;
-	
-	if (!file || file[0] == 0) {
+	struct inclfile *fi;
+
+	if (ast_strlen_zero(file)) {
 		if (configfile[0] == '/')
 			ast_copy_string(fn, configfile, fn_size);
 		else
 			snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
-	} else if (file[0] == '/') 
+	} else if (file[0] == '/')
 		ast_copy_string(fn, file, fn_size);
 	else
 		snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
 	lookup.fname = fn;
-	*fi = ao2_find(fileset, &lookup, OBJ_POINTER);
-	if (!(*fi)) {
-		/* set up a file scratch pad */
-		struct inclfile *fx = ao2_alloc(sizeof(struct inclfile), inclfile_destroy);
-		fx->fname = ast_strdup(fn);
-		fx->lineno = 1;
-		*fi = fx;
-		ao2_link(fileset, fx);
-	}
+	fi = ao2_find(fileset, &lookup, OBJ_POINTER);
+	if (fi) {
+		/* Found existing include file scratch pad. */
+		return fi;
+	}
+
+	/* set up a file scratch pad */
+	fi = ao2_alloc(sizeof(struct inclfile), inclfile_destroy);
+	if (!fi) {
+		/* Scratch pad creation failed. */
+		return NULL;
+	}
+	fi->fname = ast_strdup(fn);
+	if (!fi->fname) {
+		/* Scratch pad creation failed. */
+		ao2_ref(fi, -1);
+		return NULL;
+	}
+	fi->lineno = 1;
+
+	ao2_link(fileset, fi);
+
+	return fi;
 }
 
 static int count_linefeeds(char *str)
@@ -1583,8 +1739,15 @@
 
 static void insert_leading_blank_lines(FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno)
 {
-	int precomment_lines = count_linefeeds_in_comments(precomments);
+	int precomment_lines;
 	int i;
+
+	if (!fi) {
+		/* No file scratch pad object so insert no blank lines. */
+		return;
+	}
+
+	precomment_lines = count_linefeeds_in_comments(precomments);
 
 	/* I don't have to worry about those ;! comments, they are
 	   stored in the precomments, but not printed back out.
@@ -1618,65 +1781,76 @@
 int ast_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator)
 {
 	FILE *f;
-	char fn[256];
+	char fn[PATH_MAX];
 	struct ast_variable *var;
 	struct ast_category *cat;
 	struct ast_comment *cmt;
 	struct ast_config_include *incl;
 	int blanklines = 0;
-	struct ao2_container *fileset = ao2_container_alloc(180000, hash_string, hashtab_compare_strings);
-	struct inclfile *fi = 0;
+	struct ao2_container *fileset;
+	struct inclfile *fi;
+
+	fileset = ao2_container_alloc(1023, hash_string, hashtab_compare_strings);
+	if (!fileset) {
+		/* Container creation failed. */
+		return -1;
+	}
 
 	/* reset all the output flags, in case this isn't our first time saving this data */
-
-	for (incl=cfg->includes; incl; incl = incl->next)
+	for (incl = cfg->includes; incl; incl = incl->next) {
 		incl->output = 0;
+	}
 
 	/* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
 	   are all truncated to zero bytes and have that nice header*/
-
-	for (incl=cfg->includes; incl; incl = incl->next)
-	{
+	for (incl = cfg->includes; incl; incl = incl->next) {
 		if (!incl->exec) { /* leave the execs alone -- we'll write out the #exec directives, but won't zero out the include files or exec files*/
-			FILE *f1;
-
-			set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset, &fi); /* normally, fn is just set to incl->included_file, prepended with config dir if relative */
-			f1 = fopen(fn,"w");
-			if (f1) {
-				gen_header(f1, configfile, fn, generator);
-				fclose(f1); /* this should zero out the file */
+			/* normally, fn is just set to incl->included_file, prepended with config dir if relative */
+			fi = set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset);
+			f = fopen(fn, "w");
+			if (f) {
+				gen_header(f, configfile, fn, generator);
+				fclose(f); /* this should zero out the file */
 			} else {
 				ast_debug(1, "Unable to open for writing: %s\n", fn);
 				ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
 			}
-			ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
-			fi = 0;
-		}
-	}
-
-	set_fn(fn, sizeof(fn), 0, configfile, fileset, &fi); /* just set fn to absolute ver of configfile */
-#ifdef __CYGWIN__	
-	if ((f = fopen(fn, "w+"))) {
+			if (fi) {
+				ao2_ref(fi, -1);
+			}
+		}
+	}
+
+	/* just set fn to absolute ver of configfile */
+	fi = set_fn(fn, sizeof(fn), 0, configfile, fileset);
+	if (
+#ifdef __CYGWIN__
+		(f = fopen(fn, "w+"))
 #else
-	if ((f = fopen(fn, "w"))) {
-#endif	    
+		(f = fopen(fn, "w"))
+#endif
+		) {
 		ast_verb(2, "Saving '%s': ", fn);
 		gen_header(f, configfile, fn, generator);
 		cat = cfg->root;
 		fclose(f);
-		ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
-		
+		if (fi) {
+			ao2_ref(fi, -1);
+		}
+
 		/* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
-		/* since each var, cat, and associated comments can come from any file, we have to be 
+		/* since each var, cat, and associated comments can come from any file, we have to be
 		   mobile, and open each file, print, and close it on an entry-by-entry basis */
 
 		while (cat) {
-			set_fn(fn, sizeof(fn), cat->file, configfile, fileset, &fi);
+			fi = set_fn(fn, sizeof(fn), cat->file, configfile, fileset);
 			f = fopen(fn, "a");
-			if (!f)
-			{
+			if (!f) {
 				ast_debug(1, "Unable to open for writing: %s\n", fn);
 				ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
+				if (fi) {
+					ao2_ref(fi, -1);
+				}
 				ao2_ref(fileset, -1);
 				return -1;
 			}
@@ -1737,9 +1911,10 @@
 					fprintf(f,"%s", cmt->cmt);
 			}
 			fclose(f);
-			ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
-			fi = 0;
-			
+			if (fi) {
+				ao2_ref(fi, -1);
+			}
+
 			var = cat->root;
 			while (var) {
 				struct ast_category_template_instance *x;
@@ -1759,18 +1934,18 @@
 					var = var->next;
 					continue;
 				}
-				set_fn(fn, sizeof(fn), var->file, configfile, fileset, &fi);
+				fi = set_fn(fn, sizeof(fn), var->file, configfile, fileset);
 				f = fopen(fn, "a");
-				if (!f)
-				{
+				if (!f) {
 					ast_debug(1, "Unable to open for writing: %s\n", fn);
 					ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
-					ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
-					fi = 0;
+					if (fi) {
+						ao2_ref(fi, -1);
+					}
 					ao2_ref(fileset, -1);
 					return -1;
 				}
-				
+
 				/* dump any includes that happen before this category header */
 				for (incl=cfg->includes; incl; incl = incl->next) {
 					if (strcmp(incl->include_location_file, var->file) == 0){
@@ -1783,15 +1958,15 @@
 						}
 					}
 				}
-				
+
 				insert_leading_blank_lines(f, fi, var->precomments, var->lineno);
 				for (cmt = var->precomments; cmt; cmt=cmt->next) {
 					if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
 						fprintf(f,"%s", cmt->cmt);
 				}
-				if (var->sameline) 
+				if (var->sameline)
 					fprintf(f, "%s %s %s  %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt);
-				else	
+				else
 					fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value);
 				for (cmt = var->trailing; cmt; cmt=cmt->next) {
 					if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
@@ -1802,11 +1977,12 @@
 					while (blanklines--)
 						fprintf(f, "\n");
 				}
-				
+
 				fclose(f);
-				ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
-				fi = 0;
-				
+				if (fi) {
+					ao2_ref(fi, -1);
+				}
+
 				var = var->next;
 			}
 			cat = cat->next;
@@ -1816,29 +1992,30 @@
 	} else {
 		ast_debug(1, "Unable to open for writing: %s\n", fn);
 		ast_verb(2, "Unable to write (%s)", strerror(errno));
-		ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
+		if (fi) {
+			ao2_ref(fi, -1);
+		}
 		ao2_ref(fileset, -1);
 		return -1;
 	}
 
 	/* Now, for files with trailing #include/#exec statements,
 	   we have to make sure every entry is output */
-
 	for (incl=cfg->includes; incl; incl = incl->next) {
 		if (!incl->output) {
 			/* open the respective file */
-			set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset, &fi);
+			fi = set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset);
 			f = fopen(fn, "a");
-			if (!f)
-			{
+			if (!f) {
 				ast_debug(1, "Unable to open for writing: %s\n", fn);
 				ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
-				ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
-				fi = 0;
+				if (fi) {
+					ao2_ref(fi, -1);
+				}
 				ao2_ref(fileset, -1);
 				return -1;
 			}
-			
+
 			/* output the respective include */
 			if (incl->exec)
 				fprintf(f,"#exec \"%s\"\n", incl->exec_file);
@@ -1846,12 +2023,13 @@
 				fprintf(f,"#include \"%s\"\n", incl->included_file);
 			fclose(f);
 			incl->output = 1;
-			ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
-			fi = 0;
+			if (fi) {
+				ao2_ref(fi, -1);
+			}
 		}
 	}
 	ao2_ref(fileset, -1); /* this should destroy the hash container */
-				
+
 	return 0;
 }
 
@@ -1873,6 +2051,7 @@
 static int append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
 {
 	struct ast_config_map *map;
+	char *dst;
 	int length;
 
 	length = sizeof(*map);
@@ -1885,22 +2064,22 @@
 	if (!(map = ast_calloc(1, length)))
 		return -1;
 
-	map->name = map->stuff;
-	strcpy(map->name, name);
-	map->driver = map->name + strlen(map->name) + 1;
-	strcpy(map->driver, driver);
-	map->database = map->driver + strlen(map->driver) + 1;
-	strcpy(map->database, database);
+	dst = map->stuff;	/* writable space starts here */
+	map->name = strcpy(dst, name);
+	dst += strlen(dst) + 1;
+	map->driver = strcpy(dst, driver);
+	dst += strlen(dst) + 1;
+	map->database = strcpy(dst, database);
 	if (table) {
-		map->table = map->database + strlen(map->database) + 1;
-		strcpy(map->table, table);
+		dst += strlen(dst) + 1;
+		map->table = strcpy(dst, table);
 	}
 	map->priority = priority;
 	map->next = config_maps;
+	config_maps = map;
 
 	ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name);
 
-	config_maps = map;
 	return 0;
 }
 

Modified: team/irroot/distrotech-customers-10/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-10/main/pbx.c?view=diff&rev=334417&r1=334416&r2=334417
==============================================================================
--- team/irroot/distrotech-customers-10/main/pbx.c (original)
+++ team/irroot/distrotech-customers-10/main/pbx.c Sat Sep  3 04:20:19 2011
@@ -584,10 +584,9 @@
 			If the variable name is prefixed with <literal>__</literal>, the variable will be
 			inherited into channels created from the current channel and all children channels.</para>
 			<note><para>If (and only if), in <filename>/etc/asterisk/asterisk.conf</filename>, you have
-			a <literal>[compat]</literal> category, and you have <literal>app_set = 1.6</literal> under that,then
-			the behavior of this app changes, and does not strip surrounding quotes from the right hand side as
-			it did previously in 1.4. The <literal>app_set = 1.6</literal> is only inserted if <literal>make samples</literal>
-			is executed, or if users insert this by hand into the <filename>asterisk.conf</filename> file.
+			a <literal>[compat]</literal> category, and you have <literal>app_set = 1.4</literal> under that, then
+			the behavior of this app changes, and strips surrounding quotes from the right hand side as
+			it did previously in 1.4.
 			The advantages of not stripping out quoting, and not caring about the separator characters (comma and vertical bar)
 			were sufficient to make these changes in 1.6. Confusion about how many backslashes would be needed to properly
 			protect separators and quotes in various database access strings has been greatly

Modified: team/irroot/distrotech-customers-10/res/res_config_odbc.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-10/res/res_config_odbc.c?view=diff&rev=334417&r1=334416&r2=334417
==============================================================================
--- team/irroot/distrotech-customers-10/res/res_config_odbc.c (original)
+++ team/irroot/distrotech-customers-10/res/res_config_odbc.c Sat Sep  3 04:20:19 2011
@@ -1131,6 +1131,11 @@
 #undef warn_length
 #undef warn_type
 
+static int unload_odbc(const char *a, const char *b)
+{
+	return ast_odbc_clear_cache(a, b);
+}
+
 static struct ast_config_engine odbc_engine = {
 	.name = "odbc",
 	.load_func = config_odbc,
@@ -1141,7 +1146,7 @@
 	.update_func = update_odbc,
 	.update2_func = update2_odbc,
 	.require_func = require_odbc,
-	.unload_func = ast_odbc_clear_cache,
+	.unload_func = unload_odbc,
 };
 
 static int unload_module (void)

Modified: team/irroot/distrotech-customers-10/res/res_musiconhold.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-10/res/res_musiconhold.c?view=diff&rev=334417&r1=334416&r2=334417
==============================================================================
--- team/irroot/distrotech-customers-10/res/res_musiconhold.c (original)
+++ team/irroot/distrotech-customers-10/res/res_musiconhold.c Sat Sep  3 04:20:19 2011
@@ -151,6 +151,7 @@
 static int respawn_time = 20;
 
 struct moh_files_state {
+	/*! Holds a reference to the MOH class. */
 	struct mohclass *class;
 	char name[MAX_MUSICCLASS];
 	struct ast_format origwfmt;
@@ -232,7 +233,7 @@
 {
 	struct mohclass *dup;
 	if ((dup = ao2_find(mohclasses, class, OBJ_POINTER))) {
-		if (_ao2_ref_debug(dup, -1, (char *) tag, (char *) file, line, funcname) == 2) {
+		if (__ao2_ref_debug(dup, -1, (char *) tag, (char *) file, line, funcname) == 2) {
 			FILE *ref = fopen("/tmp/refs", "a");
 			if (ref) {
 				fprintf(ref, "%p =1   %s:%d:%s (%s) BAD ATTEMPT!\n", class, file, line, funcname, tag);
@@ -433,10 +434,13 @@
 		ast_module_ref(ast_module_info->self);
 	} else {
 		state = chan->music_state;
-	}
-
-	if (!state) {
-		return NULL;
+		if (!state) {
+			return NULL;
+		}
+		if (state->class) {
+			mohclass_unref(state->class, "Uh Oh. Restarting MOH with an active class");
+			ast_log(LOG_WARNING, "Uh Oh. Restarting MOH with an active class\n");
+		}
 	}
 
 	/* LOGIC: Comparing an unrefcounted pointer is a really bad idea, because
@@ -936,6 +940,12 @@
 	ast_free(moh);
 
 	if (chan) {
+		struct moh_files_state *state;
+
+		state = chan->music_state;
+		if (state && state->class) {
+			state->class = mohclass_unref(state->class, "Unreffing channel's music class upon deactivation of generator");
+		}
 		if (oldwfmt.id && ast_set_write_format(chan, &oldwfmt)) {
 			ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n",
 					chan->name, ast_getformatname(&oldwfmt));
@@ -954,13 +964,17 @@
 	/* Initiating music_state for current channel. Channel should know name of moh class */
 	if (!chan->music_state && (state = ast_calloc(1, sizeof(*state)))) {
 		chan->music_state = state;
-		state->class = mohclass_ref(class, "Copying reference into state container");
 		ast_module_ref(ast_module_info->self);
-	} else
+	} else {
 		state = chan->music_state;
-	if (state && state->class != class) {
+		if (!state) {
+			return NULL;
+		}
+		if (state->class) {
+			mohclass_unref(state->class, "Uh Oh. Restarting MOH with an active class");
+			ast_log(LOG_WARNING, "Uh Oh. Restarting MOH with an active class\n");
+		}
 		memset(state, 0, sizeof(*state));
-		state->class = class;
 	}
 
 	if ((res = mohalloc(class))) {
@@ -969,6 +983,8 @@
 			ast_log(LOG_WARNING, "Unable to set channel '%s' to format '%s'\n", chan->name, ast_codec2str(&class->format));
 			moh_release(NULL, res);
 			res = NULL;
+		} else {
+			state->class = mohclass_ref(class, "Placing reference into state container");
 		}
 		ast_verb(3, "Started music on hold, class '%s', on channel '%s'\n", class->name, chan->name);
 	}
@@ -1285,7 +1301,10 @@
 
 	if (state) {
 		if (state->class) {
-			state->class = mohclass_unref(state->class, "Channel MOH state destruction");
+			/* This should never happen.  We likely just leaked some resource. */
+			state->class =
+				mohclass_unref(state->class, "Uh Oh. Cleaning up MOH with an active class");
+			ast_log(LOG_WARNING, "Uh Oh. Cleaning up MOH with an active class\n");
 		}
 		ast_free(chan->music_state);
 		chan->music_state = NULL;




More information about the asterisk-commits mailing list