Пример #1
0
static void shared_variable_free(void *data)
{
	struct varshead *varshead = data;
	struct ast_var_t *var;

	while ((var = AST_LIST_REMOVE_HEAD(varshead, entries))) {
		ast_var_delete(var);
	}
	ast_free(varshead);
}
Пример #2
0
void ast_var_list_destroy(struct varshead *head)
{
	struct ast_var_t *var;

	if (!head) {
		return;
	}

	while ((var = AST_LIST_REMOVE_HEAD(head, entries))) {
		ast_var_delete(var);
	}

	ast_free(head);
}
Пример #3
0
static char *loopback_helper(char *buf, int buflen, const char *exten, const char *context, int priority, const char *data)
{
	struct ast_var_t *newvariable;
	struct varshead headp;
	char tmp[80];

	snprintf(tmp, sizeof(tmp), "%d", priority);
	memset(buf, 0, buflen);
	AST_LIST_HEAD_INIT_NOLOCK(&headp);
	AST_LIST_INSERT_HEAD(&headp, ast_var_assign("EXTEN", exten), entries);
	AST_LIST_INSERT_HEAD(&headp, ast_var_assign("CONTEXT", context), entries);
	AST_LIST_INSERT_HEAD(&headp, ast_var_assign("PRIORITY", tmp), entries);
	/* Substitute variables */
	pbx_substitute_variables_varshead(&headp, data, buf, buflen);
	/* free the list */
	while ((newvariable = AST_LIST_REMOVE_HEAD(&headp, entries)))
                ast_var_delete(newvariable);
	return buf;
}
Пример #4
0
/*! \brief
 * the string is 'prefix:data' or prefix:fmt:data'
 * with ':' being invalid in strings.
 */
static int do_say(say_args_t *a, const char *s, const char *options, int depth)
{
	struct ast_variable *v;
	char *lang, *x, *rule = NULL;
	int ret = 0;   
	struct varshead head = { .first = NULL, .last = NULL };
	struct ast_var_t *n;

	ast_debug(2, "string <%s> depth <%d>\n", s, depth);
	if (depth++ > 10) {
		ast_log(LOG_WARNING, "recursion too deep, exiting\n");
		return -1;
	} else if (!say_cfg) {
		ast_log(LOG_WARNING, "no say.conf, cannot spell '%s'\n", s);
		return -1;
	}

	/* scan languages same as in file.c */
	if (a->language == NULL)
		a->language = "en";     /* default */
	ast_debug(2, "try <%s> in <%s>\n", s, a->language);
	lang = ast_strdupa(a->language);
	for (;;) {
		for (v = ast_variable_browse(say_cfg, lang); v ; v = v->next) {
			if (ast_extension_match(v->name, s)) {
				rule = ast_strdupa(v->value);
				break;
			}
		}
		if (rule)
			break;
		if ( (x = strchr(lang, '_')) )
			*x = '\0';      /* try without suffix */
		else if (strcmp(lang, "en"))
			lang = "en";    /* last resort, try 'en' if not done yet */
		else
			break;
	}
	if (!rule)
		return 0;

	/* skip up to two prefixes to get the value */
	if ( (x = strchr(s, ':')) )
		s = x + 1;
	if ( (x = strchr(s, ':')) )
		s = x + 1;
	ast_debug(2, "value is <%s>\n", s);
	n = ast_var_assign("SAY", s);
	if (!n) {
		ast_log(LOG_ERROR, "Memory allocation error in do_say\n");
		return -1;
	}
	AST_LIST_INSERT_HEAD(&head, n, entries);

	/* scan the body, one piece at a time */
	while ( !ret && (x = strsep(&rule, ",")) ) { /* exit on key */
		char fn[128];
		const char *p, *fmt, *data; /* format and data pointers */

		/* prepare a decent file name */
		x = ast_skip_blanks(x);
		ast_trim_blanks(x);

		/* replace variables */
		pbx_substitute_variables_varshead(&head, x, fn, sizeof(fn));
		ast_debug(2, "doing [%s]\n", fn);

		/* locate prefix and data, if any */
		fmt = strchr(fn, ':');
		if (!fmt || fmt == fn)	{	/* regular filename */
			ret = s_streamwait3(a, fn);
			continue;
		}
		fmt++;
		data = strchr(fmt, ':');	/* colon before data */
		if (!data || data == fmt) {	/* simple prefix-fmt */
			ret = do_say(a, fn, options, depth);
			continue;
		}
		/* prefix:fmt:data */
		for (p = fmt; p < data && ret <= 0; p++) {
			char fn2[sizeof(fn)];
			if (*p == ' ' || *p == '\t')	/* skip blanks */
				continue;
			if (*p == '\'') {/* file name - we trim them */
				char *y;
				strcpy(fn2, ast_skip_blanks(p+1));	/* make a full copy */
				y = strchr(fn2, '\'');
				if (!y) {
					p = data;	/* invalid. prepare to end */
					break;
				}
				*y = '\0';
				ast_trim_blanks(fn2);
				p = strchr(p+1, '\'');
				ret = s_streamwait3(a, fn2);
			} else {
				int l = fmt-fn;
				strcpy(fn2, fn); /* copy everything */
				/* after prefix, append the format */
				fn2[l++] = *p;
				strcpy(fn2 + l, data);
				ret = do_say(a, fn2, options, depth);
			}
			
			if (ret) {
				break;
			}
		}
	}
	ast_var_delete(n);
	return ret;
}