static int custom_log(struct ast_cdr *cdr)
{
	/* Make sure we have a big enough buf */
	char buf[2048];
	struct ast_channel dummy;

	/* Abort if no master file is specified */
	if (ast_strlen_zero(master))
		return 0;

	memset(buf, 0 , sizeof(buf));
	/* Quite possibly the first use of a static struct ast_channel, we need it so the var funcs will work */
	memset(&dummy, 0, sizeof(dummy));
	dummy.cdr = cdr;
	pbx_substitute_variables_helper(&dummy, format, buf, sizeof(buf) - 1);

	/* because of the absolutely unconditional need for the
	   highest reliability possible in writing billing records,
	   we open write and close the log file each time */
	mf = fopen(master, "a");
	if (!mf) {
		ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", master, strerror(errno));
	}
	if (mf) {
		fputs(buf, mf);
		fflush(mf); /* be particularly anal here */
		fclose(mf);
		mf = NULL;
	}
	return 0;
}
static enum ast_test_result_state test_chan_variable(struct ast_test *test,
		struct ast_channel *c, const char *varname)
{
	const char *values[] = { "one", "three", "reallylongdinosaursoundingthingwithwordsinit" };
	int i, okay = 1;
	char workspace[4096];
	struct ast_str *str = ast_str_create(16);
	struct ast_str *var = ast_str_create(16);

	ast_str_set(&var, 0, "${%s}", varname);
	for (i = 0; i < ARRAY_LEN(values); i++) {
		pbx_builtin_setvar_helper(c, varname, values[i]);
		ast_str_substitute_variables(&str, 0, c, ast_str_buffer(var));
		pbx_substitute_variables_helper(c, ast_str_buffer(var), workspace, sizeof(workspace));
		ast_test_status_update(test, "Testing '%s' . . . . . %s\n",
				ast_str_buffer(var), okay ? "passed" : "FAILED");
		if (strcmp(values[i], ast_str_buffer(str)) != 0 || strcmp(values[i], workspace) != 0) {
			ast_test_status_update(test, "%s != %s != %s\n",
					values[i], ast_str_buffer(str), workspace);
			okay = 0;
		}
	}

	ast_free(str);
	ast_free(var);

	return okay ? AST_TEST_PASS : AST_TEST_FAIL;
}
Exemple #3
0
static int exec_exec(struct ast_channel *chan, void *data)
{
	int res = 0;
	char *s, *appname, *endargs, args[MAXRESULT];
	struct ast_app *app;

	if (ast_strlen_zero(data))
		return 0;

	s = ast_strdupa(data);
	args[0] = 0;
	appname = strsep(&s, "(");
	if (s) {
		endargs = strrchr(s, ')');
		if (endargs)
			*endargs = '\0';
		pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
	}
	if (appname) {
		app = pbx_findapp(appname);
		if (app) {
			res = pbx_exec(chan, app, args);
		} else {
			ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
			res = -1;
		}
	}

	return res;
}
Exemple #4
0
static int eval_exec(struct cw_channel *chan, int argc, char **argv)
{
	static int dep_warning = 0;
	char tmp[MAXRESULT];
	struct localuser *u;
	char *newvar = NULL;
	int res = 0;

	if (!dep_warning) {
		cw_log(LOG_WARNING, "This application has been deprecated in favor of the dialplan function, EVAL\n");
		dep_warning = 1;
	}

	LOCAL_USER_ADD(u);
	
	/* Check and parse arguments */
	if (argv[0]) {
		newvar = strsep(&argv[0], "=");
		if (newvar && (newvar[0] != '\0')) {
			pbx_substitute_variables_helper(chan, argv[0], tmp, sizeof(tmp));
			pbx_builtin_setvar_helper(chan, newvar, tmp);
		}
	}

	LOCAL_USER_REMOVE(u);
	return res;
}
static int tryexec_exec(struct ast_channel *chan, void *data)
{
	int res=0;
	struct localuser *u;
	char *s, *appname, *endargs, args[MAXRESULT] = "";
	struct ast_app *app;

	LOCAL_USER_ADD(u);

	/* Check and parse arguments */
	if (data) {
		s = ast_strdupa(data);
		appname = strsep(&s, "(");
		if (s) {
			endargs = strrchr(s, ')');
			if (endargs)
				*endargs = '\0';
			pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
		}
		if (appname) {
			app = pbx_findapp(appname);
			if (app) {
				res = pbx_exec(chan, app, args);
				pbx_builtin_setvar_helper(chan, "TRYSTATUS", res ? "FAILED" : "SUCCESS");
			} else {
				ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
				pbx_builtin_setvar_helper(chan, "TRYSTATUS", "NOAPP");
			}
		}
	}

	LOCAL_USER_REMOVE(u);
	return 0;
}
static int eval_exec(struct ast_channel *chan, void *data)
{
	int res=0;
	struct localuser *u;
	char *s, *newvar=NULL, tmp[MAXRESULT];
	static int dep_warning = 0;

	LOCAL_USER_ADD(u);
	
	if (!dep_warning) {
		ast_log(LOG_WARNING, "This application has been deprecated in favor of the dialplan function, EVAL\n");
		dep_warning = 1;
	}

	/* Check and parse arguments */
	if (data) {
		s = ast_strdupa((char *)data);
		if (s) {
			newvar = strsep(&s, "=");
			if (newvar && (newvar[0] != '\0')) {
				memset(tmp, 0, MAXRESULT);
				pbx_substitute_variables_helper(chan, s, tmp, MAXRESULT - 1);
				pbx_builtin_setvar_helper(chan, newvar, tmp);
			}
		} else {
			ast_log(LOG_ERROR, "Out of memory\n");
			res = -1;
		}
	}

	LOCAL_USER_REMOVE(u);
	return res;
}
Exemple #7
0
static int exec_exec(struct ast_channel *chan, void *data)
{
	int res=0;
	struct ast_module_user *u;
	char *s, *appname, *endargs, args[MAXRESULT] = "";
	struct ast_app *app;

	u = ast_module_user_add(chan);

	/* Check and parse arguments */
	if (data) {
		s = ast_strdupa(data);
		appname = strsep(&s, "(");
		if (s) {
			endargs = strrchr(s, ')');
			if (endargs)
				*endargs = '\0';
			pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
		}
		if (appname) {
			app = pbx_findapp(appname);
			if (app) {
				res = pbx_exec(chan, app, args);
			} else {
				ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
				res = -1;
			}
		}
	}

	ast_module_user_remove(u);
	return res;
}
static enum ast_test_result_state test_chan_string(struct ast_test *test,
		struct ast_channel *c, char *cfield, size_t cfieldsize,
		const char *expression)
{
	const char *values[] = { "one", "three", "reallylongdinosaursoundingthingwithwordsinit" };
	int i, okay = 1;
	char workspace[4096];
	struct ast_str *str = ast_str_create(16);

	for (i = 0; i < ARRAY_LEN(values); i++) {
		ast_copy_string(cfield, values[i], cfieldsize);
		ast_str_substitute_variables(&str, 0, c, expression);
		pbx_substitute_variables_helper(c, expression, workspace, sizeof(workspace));
		ast_test_status_update(test, "Testing '%s' . . . . . %s\n",
				expression, okay ? "passed" : "FAILED");
		if (strcmp(cfield, ast_str_buffer(str)) != 0 || strcmp(cfield, workspace) != 0) {
			ast_test_status_update(test, "%s != %s != %s\n", cfield, ast_str_buffer(str), workspace);
			okay = 0;
		}
	}

	ast_free(str);

	return okay ? AST_TEST_PASS : AST_TEST_FAIL;
}
static int SQLiteSwitch_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data)
{
	struct ast_app *app;
	int res = 0;
	extension_cache *cache;
	char key[ARRAY_SIZE];
	time_t now;
	char app_data[1024];
	

	time(&now);
	//ast_log(LOG_NOTICE, "SQLiteSwitch_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);

	snprintf(key, ARRAY_SIZE, "%s.%s", exten, context);
	memset(&app_data,0,sizeof(app_data) - 1);

	ast_verbose(VERBOSE_PREFIX_2 "SQLiteSwitch_exec lookup [%s]: ",key);
	cache = (extension_cache *) sqlite3HashFind(&extens,key,strlen(key));
	ast_verbose("%s\n",cache ? "match" : "fail");

	if (cache) {
		app = pbx_findapp(cache->app_name[priority]);
		if (app) {
			pbx_substitute_variables_helper(chan, cache->app_data[priority], app_data, sizeof(app_data) - 1);
			ast_verbose(VERBOSE_PREFIX_2 "SQLiteSwitch_exec: call app %s(%s)\n",cache->app_name[priority],app_data);
			res = pbx_exec(chan, app,app_data,1);
		}
		else {
			ast_log(LOG_WARNING, "application %s not registered\n",cache->app_name[priority]);
			res = -1;
		}
	}
		
	return res;
}
Exemple #10
0
static char *function_eval(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len) 
{
	if (argc != 1 || !argv[0][0]) {
		cw_log(LOG_ERROR, "Syntax: %s\n", eval_func_syntax);
		return NULL;
	}

	pbx_substitute_variables_helper(chan, argv[0], buf, len);

	return buf;
}
/*!
 * \brief Execute an DELETE query
 * \param url
 * \param unused
 * \param keyfield where clause field
 * \param lookup value of field for where clause
 * \param ap list containing one or more field/value set(s)
 *
 * Delete a row from a database table, prepare the sql statement using keyfield and lookup
 * control the number of records to change. Additional params to match rows are stored in ap list.
 * Sub-in the values to the prepared statement and execute it.
 *
 * \retval number of rows affected
 * \retval -1 on failure
*/
static int destroy_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, va_list ap)
{
	struct ast_str *query;
	char buf1[200], buf2[200];
	const char *newparam, *newval;
	char *stringp;
	int i, rowcount = -1;
	const int EncodeSpecialChars = 1, bufsize = 100;
	char *buffer;

	if (!ast_custom_function_find("CURL")) {
		ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
		return -1;
	}

	if (!(query = ast_str_create(1000)))
		return -1;

	if (!(buffer = ast_malloc(bufsize))) {
		ast_free(query);
		return -1;
	}

	ast_uri_encode(keyfield, buf1, sizeof(buf1), EncodeSpecialChars);
	ast_uri_encode(lookup, buf2, sizeof(buf2), EncodeSpecialChars);
	ast_str_set(&query, 0, "${CURL(%s/destroy,%s=%s&", url, buf1, buf2);

	for (i = 0; (newparam = va_arg(ap, const char *)); i++) {
		newval = va_arg(ap, const char *);
		ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars);
		ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars);
		ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2);
	}
	va_end(ap);

	ast_str_append(&query, 0, ")}");
	pbx_substitute_variables_helper(NULL, query->str, buffer, bufsize);

	/* Line oriented output */
	stringp = buffer;
	while (*stringp <= ' ')
		stringp++;
	sscanf(stringp, "%d", &rowcount);

	ast_free(buffer);
	ast_free(query);

	if (rowcount >= 0)
		return (int)rowcount;

	return -1;
}
Exemple #12
0
static int syslog_log(struct ast_cdr *cdr)
{
	char buf[2048];
	struct ast_channel dummy;

	if (ast_strlen_zero(master))
		return 0;

	memset(buf, 0 , sizeof(buf));
	memset(&dummy, 0, sizeof(dummy));
	dummy.cdr = cdr;
	pbx_substitute_variables_helper(&dummy, format, buf, sizeof(buf) - 1);
	ast_log(LOG_CDR, "%s", buf);
	return 0;
}
static enum ast_test_result_state test_chan_function(struct ast_test *test,
		struct ast_channel *c, const char *expression)
{
	int okay = 1;
	char workspace[4096];
	struct ast_str *str = ast_str_create(16);

	ast_str_substitute_variables(&str, 0, c, expression);
	pbx_substitute_variables_helper(c, expression, workspace, sizeof(workspace));
	ast_test_status_update(test, "Testing '%s' . . . . . %s\n",
			expression, okay ? "passed" : "FAILED");
	if (strcmp(workspace, ast_str_buffer(str)) != 0) {
		ast_test_status_update(test, "test_chan_function, expr: '%s' ... %s != %s\n",
				expression, ast_str_buffer(str), workspace);
		okay = 0;
	}

	ast_free(str);

	return okay ? AST_TEST_PASS : AST_TEST_FAIL;
}
static enum ast_test_result_state test_chan_integer(struct ast_test *test,
		struct ast_channel *c, int *ifield, const char *expression)
{
	int i, okay = 1, value1 = -1, value2 = -1;
	char workspace[4096];
	struct ast_str *str = ast_str_create(16);

	ast_test_status_update(test, "Testing '%s' . . . . . %s\n", expression, okay ? "passed" : "FAILED");
	for (i = 0; i < 256; i++) {
		*ifield = i;
		ast_str_substitute_variables(&str, 0, c, expression);
		pbx_substitute_variables_helper(c, expression, workspace, sizeof(workspace));
		if (sscanf(workspace, "%d", &value1) != 1 || value1 != i || sscanf(ast_str_buffer(str), "%d", &value2) != 1 || value2 != i) {
			ast_test_status_update(test, "%s != %s and/or %d != %d != %d\n", ast_str_buffer(str), workspace, value1, value2, i);
			okay = 0;
		}
	}

	ast_free(str);

	return okay ? AST_TEST_PASS : AST_TEST_FAIL;
}
static int cut_internal(struct ast_channel *chan, char *data, char *buffer, size_t buflen)
{
	char *s, *args[3], *varname=NULL, *delimiter=NULL, *field=NULL;
	int args_okay = 0;

	memset(buffer, 0, buflen);

	/* Check and parse arguments */
	if (data) {
		s = ast_strdupa((char *)data);
		if (s) {
			ast_app_separate_args(s, '|', args, 3);
			varname = args[0];
			delimiter = args[1];
			field = args[2];

			if (field) {
				args_okay = 1;
			}
		} else {
			return ERROR_NOMEM;
		}
	}

	if (args_okay) {
		char d, ds[2];
		char *tmp = alloca(strlen(varname) + 4);
		char varvalue[MAXRESULT], *tmp2=varvalue;

		if (tmp) {
			snprintf(tmp, strlen(varname) + 4, "${%s}", varname);
			memset(varvalue, 0, sizeof(varvalue));
		} else {
			return ERROR_NOMEM;
		}

		if (delimiter[0])
			d = delimiter[0];
		else
			d = '-';

		/* String form of the delimiter, for use with strsep(3) */
		snprintf(ds, sizeof(ds), "%c", d);

		pbx_substitute_variables_helper(chan, tmp, tmp2, MAXRESULT - 1);

		if (tmp2) {
			int curfieldnum = 1;
			while ((tmp2 != NULL) && (field != NULL)) {
				char *nextgroup = strsep(&field, "&");
				int num1 = 0, num2 = MAXRESULT;
				char trashchar;

				if (sscanf(nextgroup, "%d-%d", &num1, &num2) == 2) {
					/* range with both start and end */
				} else if (sscanf(nextgroup, "-%d", &num2) == 1) {
					/* range with end */
					num1 = 0;
				} else if ((sscanf(nextgroup, "%d%c", &num1, &trashchar) == 2) && (trashchar == '-')) {
					/* range with start */
					num2 = MAXRESULT;
				} else if (sscanf(nextgroup, "%d", &num1) == 1) {
					/* single number */
					num2 = num1;
				} else {
					return ERROR_USAGE;
				}

				/* Get to start, if any */
				if (num1 > 0) {
					while ((tmp2 != (char *)NULL + 1) && (curfieldnum < num1)) {
						tmp2 = index(tmp2, d) + 1;
						curfieldnum++;
					}
				}

				/* Most frequent problem is the expectation of reordering fields */
				if ((num1 > 0) && (curfieldnum > num1)) {
					ast_log(LOG_WARNING, "We're already past the field you wanted?\n");
				}

				/* Re-null tmp2 if we added 1 to NULL */
				if (tmp2 == (char *)NULL + 1)
					tmp2 = NULL;

				/* Output fields until we either run out of fields or num2 is reached */
				while ((tmp2 != NULL) && (curfieldnum <= num2)) {
					char *tmp3 = strsep(&tmp2, ds);
					int curlen = strlen(buffer);

					if (curlen) {
						snprintf(buffer + curlen, buflen - curlen, "%c%s", d, tmp3);
					} else {
						snprintf(buffer, buflen, "%s", tmp3);
					}

					curfieldnum++;
				}
			}
		}
	} else {
		return ERROR_NOARG;
	}
	return 0;
}
Exemple #16
0
static char *function_cut(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len)
{
	char varvalue[MAXRESULT], *tmp2;
	char *field=NULL;
	char *tmp;
	char d, ds[2];
	int curfieldnum;


	if (argc != 3 || !argv[0][0] || !argv[2][0]) {
		cw_log(LOG_ERROR, "Syntax: %s\n", cut_func_syntax);
		return NULL;
	}

	tmp = alloca(strlen(argv[0]) + 4);
	snprintf(tmp, strlen(argv[0]) + 4, "${%s}", argv[0]);

	d = (argc > 1 && argv[1][0] ? argv[1][0] : '-');
	field = (argc > 2 && argv[2] ? argv[2] : "1");

	/* String form of the delimiter, for use with strsep(3) */
	snprintf(ds, sizeof(ds), "%c", d);

	pbx_substitute_variables_helper(chan, tmp, varvalue, sizeof(varvalue));

	tmp2 = varvalue;
	curfieldnum = 1;
	while ((tmp2 != NULL) && (field != NULL)) {
		char *nextgroup = strsep(&field, "&");
		int num1 = 0, num2 = MAXRESULT;
		char trashchar;

		if (sscanf(nextgroup, "%d-%d", &num1, &num2) == 2) {
			/* range with both start and end */
		} else if (sscanf(nextgroup, "-%d", &num2) == 1) {
		/* range with end */
			num1 = 0;
		} else if ((sscanf(nextgroup, "%d%c", &num1, &trashchar) == 2) && (trashchar == '-')) {
			/* range with start */
			num2 = MAXRESULT;
		} else if (sscanf(nextgroup, "%d", &num1) == 1) {
			/* single number */
			num2 = num1;
		} else {
			cw_log(LOG_ERROR, "Usage: CUT(<varname>,<char-delim>,<range-spec>)\n");
			return buf;
		}

		/* Get to start, if any */
		if (num1 > 0) {
			while ((tmp2 != (char *)NULL + 1) && (curfieldnum < num1)) {
				tmp2 = index(tmp2, d) + 1;
				curfieldnum++;
			}
		}

		/* Most frequent problem is the expectation of reordering fields */
		if ((num1 > 0) && (curfieldnum > num1)) {
			cw_log(LOG_WARNING, "We're already past the field you wanted?\n");
		}

		/* Re-null tmp2 if we added 1 to NULL */
		if (tmp2 == (char *)NULL + 1)
			tmp2 = NULL;

		/* Output fields until we either run out of fields or num2 is reached */
		while ((tmp2 != NULL) && (curfieldnum <= num2)) {
			char *tmp3 = strsep(&tmp2, ds);
			int curlen = strlen(buf);

			if (curlen) {
				snprintf(buf + curlen, len - curlen, "%c%s", d, tmp3);
			} else {
				snprintf(buf, len, "%s", tmp3);
			}

			curfieldnum++;
		}
	}
	return buf;
}
/*!
 * \brief Excute an Select query and return ast_config list
 * \param url
 * \param unused
 * \param ap list containing one or more field/operator/value set.
 *
 * \retval struct ast_config pointer on success
 * \retval NULL on failure
*/
static struct ast_config *realtime_multi_curl(const char *url, const char *unused, va_list ap)
{
	struct ast_str *query;
	char buf1[200], buf2[200];
	const char *newparam, *newval;
	char *stringp, *line, *pair, *key, *initfield = NULL;
	int i;
	const int EncodeSpecialChars = 1, bufsize = 256000;
	struct ast_variable *var=NULL;
	struct ast_config *cfg=NULL;
	struct ast_category *cat=NULL;
	char *buffer;

	if (!ast_custom_function_find("CURL")) {
		ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
		return NULL;
	}

	if (!(query = ast_str_create(1000)))
		return NULL;

	if (!(buffer = ast_malloc(bufsize))) {
		ast_free(query);
		return NULL;
	}

	ast_str_set(&query, 0, "${CURL(%s/multi,", url);

	for (i = 0; (newparam = va_arg(ap, const char *)); i++) {
		newval = va_arg(ap, const char *);
		if (i == 0) {
			char *op;
			initfield = ast_strdupa(newparam);
			if ((op = strchr(initfield, ' ')))
				*op = '\0';
		}
		ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars);
		ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars);
		ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2);
	}
	va_end(ap);

	ast_str_append(&query, 0, ")}");

	/* Do the CURL query */
	pbx_substitute_variables_helper(NULL, query->str, buffer, bufsize);

	if (!(cfg = ast_config_new()))
		goto exit_multi;

	/* Line oriented output */
	stringp = buffer;
	while ((line = strsep(&stringp, "\r\n"))) {
		if (ast_strlen_zero(line))
			continue;

		if (!(cat = ast_category_new("", "", 99999)))
			continue;

		while ((pair = strsep(&line, "&"))) {
			key = strsep(&pair, "=");
			ast_uri_decode(key);
			if (pair)
				ast_uri_decode(pair);

			if (!strcasecmp(key, initfield) && pair)
				ast_category_rename(cat, pair);

			if (!ast_strlen_zero(key)) {
				var = ast_variable_new(key, S_OR(pair, ""), "");
				ast_variable_append(cat, var);
			}
		}
		ast_category_append(cfg, cat);
	}

exit_multi:
	ast_free(buffer);
	ast_free(query);
	return cfg;
}
static struct ast_config *config_curl(const char *url, const char *unused, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *sugg_incl, const char *who_asked)
{
	struct ast_str *query;
	char buf1[200];
	char *stringp, *line, *pair, *key;
	const int EncodeSpecialChars = 1, bufsize = 256000;
	int last_cat_metric = -1, cat_metric = -1;
	struct ast_category *cat=NULL;
	char *buffer, *cur_cat = "";
	char *category = "", *var_name = "", *var_val = "";
	struct ast_flags loader_flags = { 0 };

	if (!ast_custom_function_find("CURL")) {
		ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
		return NULL;
	}

	if (!(query = ast_str_create(1000)))
		return NULL;

	if (!(buffer = ast_malloc(bufsize))) {
		ast_free(query);
		return NULL;
	}

	ast_uri_encode(file, buf1, sizeof(buf1), EncodeSpecialChars);
	ast_str_set(&query, 0, "${CURL(%s/static?file=%s)}", url, buf1);

	/* Do the CURL query */
	pbx_substitute_variables_helper(NULL, query->str, buffer, bufsize);

	/* Line oriented output */
	stringp = buffer;
	cat = ast_config_get_current_category(cfg);

	while ((line = strsep(&stringp, "\r\n"))) {
		if (ast_strlen_zero(line))
			continue;

		while ((pair = strsep(&line, "&"))) {
			key = strsep(&pair, "=");
			ast_uri_decode(key);
			if (pair)
				ast_uri_decode(pair);

			if (!strcasecmp(key, "category"))
				category = S_OR(pair, "");
			else if (!strcasecmp(key, "var_name"))
				var_name = S_OR(pair, "");
			else if (!strcasecmp(key, "var_val"))
				var_val = S_OR(pair, "");
			else if (!strcasecmp(key, "cat_metric"))
				cat_metric = pair ? atoi(pair) : 0;
		}

		if (!strcmp(var_name, "#include")) {
			if (!ast_config_internal_load(var_val, cfg, loader_flags, "", who_asked))
				return NULL;
		}

		if (strcmp(category, cur_cat) || last_cat_metric != cat_metric) {
			if (!(cat = ast_category_new(category, "", 99999)))
				break;
			cur_cat = category;
			last_cat_metric = cat_metric;
			ast_category_append(cfg, cat);
		}
		ast_variable_append(cat, ast_variable_new(var_name, var_val, ""));
	}

	ast_free(buffer);
	ast_free(query);
	return cfg;
}
/*!
 * \brief Execute a curl query and return ast_variable list
 * \param url The base URL from which to retrieve data
 * \param unused Not currently used
 * \param ap list containing one or more field/operator/value set.
 *
 * \retval var on success
 * \retval NULL on failure
*/
static struct ast_variable *realtime_curl(const char *url, const char *unused, va_list ap)
{
	struct ast_str *query;
	char buf1[200], buf2[200];
	const char *newparam, *newval;
	char *stringp, *pair, *key;
	int i;
	struct ast_variable *var=NULL, *prev=NULL;
	const int EncodeSpecialChars = 1, bufsize = 64000;
	char *buffer;

	if (!ast_custom_function_find("CURL")) {
		ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
		return NULL;
	}

	if (!(query = ast_str_create(1000)))
		return NULL;

	if (!(buffer = ast_malloc(bufsize))) {
		ast_free(query);
		return NULL;
	}

	ast_str_set(&query, 0, "${CURL(%s/single,", url);

	for (i = 0; (newparam = va_arg(ap, const char *)); i++) {
		newval = va_arg(ap, const char *);
		ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars);
		ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars);
		ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2);
	}
	va_end(ap);

	ast_str_append(&query, 0, ")}");
	pbx_substitute_variables_helper(NULL, query->str, buffer, bufsize);

	/* Remove any trailing newline characters */
	if ((stringp = strchr(buffer, '\r')) || (stringp = strchr(buffer, '\n')))
		*stringp = '\0';

	stringp = buffer;
	while ((pair = strsep(&stringp, "&"))) {
		key = strsep(&pair, "=");
		ast_uri_decode(key);
		if (pair)
			ast_uri_decode(pair);

		if (!ast_strlen_zero(key)) {
			if (prev) {
				prev->next = ast_variable_new(key, S_OR(pair, ""), "");
				if (prev->next)
					prev = prev->next;
			} else 
				prev = var = ast_variable_new(key, S_OR(pair, ""), "");
		}
	}

	ast_free(buffer);
	ast_free(query);
	return var;
}
Exemple #20
0
static int manager_log(struct ast_cdr *cdr)
{
	struct ast_tm timeresult;
	char strStartTime[80] = "";
	char strAnswerTime[80] = "";
	char strEndTime[80] = "";
	char buf[CUSTOM_FIELDS_BUF_SIZE];

	if (!enablecdr)
		return 0;

	ast_localtime(&cdr->start, &timeresult, NULL);
	ast_strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult);

	if (cdr->answer.tv_sec)	{
		ast_localtime(&cdr->answer, &timeresult, NULL);
		ast_strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult);
	}

	ast_localtime(&cdr->end, &timeresult, NULL);
	ast_strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult);

	buf[0] = '\0';
	ast_rwlock_rdlock(&customfields_lock);
	if (customfields && ast_str_strlen(customfields)) {
		struct ast_channel *dummy = ast_dummy_channel_alloc();
		if (!dummy) {
			ast_log(LOG_ERROR, "Unable to allocate channel for variable substitution.\n");
			return 0;
		}
		dummy->cdr = ast_cdr_dup(cdr);
		pbx_substitute_variables_helper(dummy, ast_str_buffer(customfields), buf, sizeof(buf) - 1);
		ast_channel_unref(dummy);
	}
	ast_rwlock_unlock(&customfields_lock);

	manager_event(EVENT_FLAG_CDR, "Cdr",
	    "AccountCode: %s\r\n"
	    "Source: %s\r\n"
	    "Destination: %s\r\n"
	    "DestinationContext: %s\r\n"
	    "CallerID: %s\r\n"
	    "Channel: %s\r\n"
	    "DestinationChannel: %s\r\n"
	    "LastApplication: %s\r\n"
	    "LastData: %s\r\n"
	    "StartTime: %s\r\n"
	    "AnswerTime: %s\r\n"
	    "EndTime: %s\r\n"
	    "Duration: %ld\r\n"
	    "BillableSeconds: %ld\r\n"
	    "Disposition: %s\r\n"
	    "AMAFlags: %s\r\n"
	    "UniqueID: %s\r\n"
	    "UserField: %s\r\n"
	    "%s",
	    cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel,
	    cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime,
	    cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition),
	    ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield,buf);

	return 0;
}
Exemple #21
0
static int pbx_load_module(void)
{
	struct ast_config *cfg;
	struct ast_variable *v;
	char *cxt, *ext, *pri, *appl, *data, *tc, *cidmatch;
	struct ast_context *con;
	char *start, *end;
	char realvalue[256];

	cfg = ast_load(config);
	if (cfg) {
		/* Use existing config to populate the PBX table */
		static_config = ast_true(ast_variable_retrieve(cfg, "general",
			"static"));
		write_protect_config = ast_true(ast_variable_retrieve(cfg, "general",
			"writeprotect"));
		v = ast_variable_browse(cfg, "globals");
		while(v) {
			memset(realvalue, 0, sizeof(realvalue));
			pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
			pbx_builtin_setvar_helper(NULL, v->name, realvalue);
			v = v->next;
		}
		cxt = ast_category_browse(cfg, NULL);
		while(cxt) {
			/* All categories but "general" or "globals" are considered contexts */
			if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) {
				cxt = ast_category_browse(cfg, cxt);
				continue;
			}
			if ((con=ast_context_create(&local_contexts,cxt, registrar))) {
				v = ast_variable_browse(cfg, cxt);
				while(v) {
					if (!strcasecmp(v->name, "exten")) {
						char *stringp=NULL;
						int ipri = -2;
						char realext[256]="";
						tc = strdup(v->value);
						if(tc!=NULL){
							stringp=tc;
							ext = strsep(&stringp, ",");
							if (!ext)
								ext="";
							pri = strsep(&stringp, ",");
							if (!pri)
								pri="";
							if (!strcmp(pri,"hint"))
								ipri=PRIORITY_HINT;
							else {
								if (sscanf(pri, "%i", &ipri) != 1) {
									ast_log(LOG_WARNING, "Invalid priority '%s' at line %d\n", pri, v->lineno);
									ipri = 0;
								}
							}
							appl = stringp;
							if (!appl)
								appl="";
							if (!(start = strchr(appl, '('))) {
								if (stringp)
									appl = strsep(&stringp, ",");
								else
									appl = "";
							}
							if (start && (end = strrchr(appl, ')'))) {
								*start = *end = '\0';
								data = start + 1;
								process_quotes_and_slashes(data, ',', '|');
							} else if (stringp!=NULL && *stringp=='"') {
								stringp++;
								data = strsep(&stringp, "\"");
								stringp++;
							} else {
								if (stringp)
									data = strsep(&stringp, ",");
								else
									data = "";
							}
							cidmatch = strchr(ext, '/');
							if (cidmatch) {
								*cidmatch = '\0';
								cidmatch++;
							}
							stringp=ext;
							strsep(&stringp, "/");

							if (!data)
								data="";
							while(*appl && (*appl < 33)) appl++;
							pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
							if (ipri) {
								if (ast_add_extension2(con, 0, realext, ipri, cidmatch, appl, strdup(data), FREE, registrar)) {
									ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
								}
							}
							free(tc);
						} else fprintf(stderr,"Error strdup returned NULL in %s\n",__PRETTY_FUNCTION__);
					} else if(!strcasecmp(v->name, "include")) {
						memset(realvalue, 0, sizeof(realvalue));
						pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
						if (ast_context_add_include2(con, realvalue, registrar))
							ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s'\n", v->value, cxt);
					} else if(!strcasecmp(v->name, "ignorepat")) {
						memset(realvalue, 0, sizeof(realvalue));
						pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
						if (ast_context_add_ignorepat2(con, realvalue, registrar))
							ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
					} else if (!strcasecmp(v->name, "switch")) {
						char *stringp=NULL;
						memset(realvalue, 0, sizeof(realvalue));
						pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
						tc = realvalue;
						stringp=tc;
						appl = strsep(&stringp, "/");
						data = strsep(&stringp, "");
						if (!data)
							data = "";
						if (ast_context_add_switch2(con, appl, data, registrar))
							ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
					}
					v = v->next;
				}
			}
			cxt = ast_category_browse(cfg, cxt);
		}
		ast_destroy(cfg);
	}
	ast_merge_contexts_and_delete(&local_contexts,registrar);

	for (con = ast_walk_contexts(NULL); con; con = ast_walk_contexts(con))
		ast_context_verify_includes(con);

	return 0;
}
static void launch_monitor_thread(struct ast_channel *chan, const char *filename,
				  unsigned int flags, int readvol, int writevol,
				  const char *post_process, const char *filename_write,
				  char *filename_read, const char *uid_channel_var)
{
	pthread_t thread;
	struct mixmonitor *mixmonitor;
	char postprocess2[1024] = "";
	char *datastore_id = NULL;

	postprocess2[0] = 0;
	/* If a post process system command is given attach it to the structure */
	if (!ast_strlen_zero(post_process)) {
		char *p1, *p2;

		p1 = ast_strdupa(post_process);
		for (p2 = p1; *p2; p2++) {
			if (*p2 == '^' && *(p2+1) == '{') {
				*p2 = '$';
			}
		}
		pbx_substitute_variables_helper(chan, p1, postprocess2, sizeof(postprocess2) - 1);
	}

	/* Pre-allocate mixmonitor structure and spy */
	if (!(mixmonitor = ast_calloc(1, sizeof(*mixmonitor)))) {
		return;
	}

	/* Setup the actual spy before creating our thread */
	if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type, 0)) {
		mixmonitor_free(mixmonitor);
		return;
	}

	/* Copy over flags and channel name */
	mixmonitor->flags = flags;
	if (!(mixmonitor->autochan = ast_autochan_setup(chan))) {
		mixmonitor_free(mixmonitor);
		return;
	}

	if (setup_mixmonitor_ds(mixmonitor, chan, &datastore_id)) {
		ast_autochan_destroy(mixmonitor->autochan);
		mixmonitor_free(mixmonitor);
		ast_free(datastore_id);
		return;
	}

	if (!ast_strlen_zero(uid_channel_var)) {
		if (datastore_id) {
			pbx_builtin_setvar_helper(chan, uid_channel_var, datastore_id);
		}
	}
	ast_free(datastore_id);


	mixmonitor->name = ast_strdup(ast_channel_name(chan));

	if (!ast_strlen_zero(postprocess2)) {
		mixmonitor->post_process = ast_strdup(postprocess2);
	}

	if (!ast_strlen_zero(filename)) {
		mixmonitor->filename = ast_strdup(filename);
	}

	if (!ast_strlen_zero(filename_write)) {
		mixmonitor->filename_write = ast_strdup(filename_write);
	}

	if (!ast_strlen_zero(filename_read)) {
		mixmonitor->filename_read = ast_strdup(filename_read);
	}

	ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_TRIGGER_SYNC);

	if (readvol)
		mixmonitor->audiohook.options.read_volume = readvol;
	if (writevol)
		mixmonitor->audiohook.options.write_volume = writevol;

	if (startmon(chan, &mixmonitor->audiohook)) {
		ast_log(LOG_WARNING, "Unable to add '%s' spy to channel '%s'\n",
			mixmonitor_spy_type, ast_channel_name(chan));
		ast_audiohook_destroy(&mixmonitor->audiohook);
		mixmonitor_free(mixmonitor);
		return;
	}

	ast_pthread_create_detached_background(&thread, NULL, mixmonitor_thread, mixmonitor);
}
Exemple #23
0
static void launch_monitor_thread(struct ast_channel *chan, const char *filename, unsigned int flags,
				  int readvol, int writevol, const char *post_process) 
{
	pthread_attr_t attr;
	pthread_t thread;
	struct mixmonitor *mixmonitor;
	char postprocess2[1024] = "";
	size_t len;

	len = sizeof(*mixmonitor) + strlen(chan->name) + strlen(filename) + 2;

	/* If a post process system command is given attach it to the structure */
	if (!ast_strlen_zero(post_process)) {
		char *p1, *p2;

		p1 = ast_strdupa(post_process);
		for (p2 = p1; *p2 ; p2++) {
			if (*p2 == '^' && *(p2+1) == '{') {
				*p2 = '$';
			}
		}

		pbx_substitute_variables_helper(chan, p1, postprocess2, sizeof(postprocess2) - 1);
		if (!ast_strlen_zero(postprocess2))
			len += strlen(postprocess2) + 1;
	}

	/* Pre-allocate mixmonitor structure and spy */
	if (!(mixmonitor = calloc(1, len))) {
		return;
	}

	/* Copy over flags and channel name */
	mixmonitor->flags = flags;
	if (setup_mixmonitor_ds(mixmonitor, chan)) {
		return;
	}
	mixmonitor->name = (char *) mixmonitor + sizeof(*mixmonitor);
	strcpy(mixmonitor->name, chan->name);
	if (!ast_strlen_zero(postprocess2)) {
		mixmonitor->post_process = mixmonitor->name + strlen(mixmonitor->name) + strlen(filename) + 2;
		strcpy(mixmonitor->post_process, postprocess2);
	}

	mixmonitor->filename = (char *) mixmonitor + sizeof(*mixmonitor) + strlen(chan->name) + 1;
	strcpy(mixmonitor->filename, filename);

	/* Setup the actual spy before creating our thread */
	if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type)) {
		free(mixmonitor);
		return;
	}
	
	ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_TRIGGER_SYNC);
	
	if (readvol)
		mixmonitor->audiohook.options.read_volume = readvol;
	if (writevol)
		mixmonitor->audiohook.options.write_volume = writevol;

	if (startmon(chan, &mixmonitor->audiohook)) {
		ast_log(LOG_WARNING, "Unable to add '%s' spy to channel '%s'\n",
			mixmonitor_spy_type, chan->name);
		/* Since we couldn't add ourselves - bail out! */
		ast_audiohook_destroy(&mixmonitor->audiohook);
		free(mixmonitor);
		return;
	}

	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	ast_pthread_create_background(&thread, &attr, mixmonitor_thread, mixmonitor);
	pthread_attr_destroy(&attr);
}