Beispiel #1
0
int ast_callerid_parse(char *instr, char **name, char **location)
{
	char *ns, *ne, *ls, *le;

	/* Try "name" <location> format or name <location> format */
	if ((ls = strrchr(instr, '<')) && (le = strrchr(ls, '>'))) {
		*ls = *le = '\0';	/* location found, trim off the brackets */
		*location = ls + 1;	/* and this is the result */
		if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
			*ns = *ne = '\0';	/* trim off the quotes */
			*name = ns + 1;		/* and this is the name */
		} else if (ns) {
			/* An opening quote was found but no closing quote was. The closing
			 * quote may actually be after the end of the bracketed number
			 */
			if (strchr(le + 1, '\"')) {
				*ns = '\0';
				*name = ns + 1;
				ast_trim_blanks(*name);
			} else {
				*name = NULL;
			}
		} else { /* no quotes, trim off leading and trailing spaces */
			*name = ast_skip_blanks(instr);
			ast_trim_blanks(*name);
		}
	} else {	/* no valid brackets */
		char tmp[256];

		ast_copy_string(tmp, instr, sizeof(tmp));
		ast_shrink_phone_number(tmp);
		if (ast_isphonenumber(tmp)) {	/* Assume it's just a location */
			*name = NULL;
			strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */
			*location = instr;
		} else { /* Assume it's just a name. */
			*location = NULL;
			if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
				*ns = *ne = '\0';	/* trim off the quotes */
				*name = ns + 1;		/* and this is the name */
			} else { /* no quotes, trim off leading and trailing spaces */
				*name = ast_skip_blanks(instr);
				ast_trim_blanks(*name);
			}
		}
	}
	return 0;
}
Beispiel #2
0
static int user_event_hook_cb(int category, const char *event, char *body)
{
	char *parse;
	char *kvp;

	if (strcmp(event, "UserEvent")) {
		return -1;
	}

	parse = ast_strdupa(body);
	while ((kvp = strsep(&parse, "\r\n"))) {
		char *key, *value;

		kvp = ast_trim_blanks(kvp);
		if (ast_strlen_zero(kvp)) {
			continue;
		}
		key = strsep(&kvp, ":");
		value = ast_skip_blanks(kvp);
		verify_user_event_fields(received_user_events, key, value);
	}

	received_user_events++;

	ast_mutex_lock(&user_event_lock);
	if (received_user_events == expected_user_events) {
		ast_cond_signal(&user_event_cond);
	}
	ast_mutex_unlock(&user_event_lock);

	return 0;
}
/*!
 * \internal
 * \brief Copies any other request header data over to ast_msg structure.
 *
 * \param rdata The SIP request
 * \param msg The msg structure to copy headers into
 */
static int headers_to_vars(const pjsip_rx_data *rdata, struct ast_msg *msg)
{
	char *c;
	char name[MAX_HDR_SIZE];
	char buf[MAX_HDR_SIZE];
	int res = 0;
	pjsip_hdr *h = rdata->msg_info.msg->hdr.next;
	pjsip_hdr *end= &rdata->msg_info.msg->hdr;

	while (h != end) {
		if ((res = pjsip_hdr_print_on(h, buf, sizeof(buf)-1)) > 0) {
			buf[res] = '\0';
			if ((c = strchr(buf, ':'))) {
				ast_copy_string(buf, ast_skip_blanks(c + 1), sizeof(buf));
			}

			ast_copy_pj_str(name, &h->name, sizeof(name));
			if ((res = ast_msg_set_var(msg, name, buf)) != 0) {
				break;
			}
		}
		h = h->next;
	}
	return 0;
}
Beispiel #4
0
static void rfc3326_use_reason_header(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
{
	const pj_str_t str_reason = { "Reason", 6 };
	pjsip_generic_string_hdr *header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_reason, NULL);
	char buf[20], *cause, *text;
	int code;

	if (!header) {
		return;
	}

	ast_copy_pj_str(buf, &header->hvalue, sizeof(buf));
	cause = ast_skip_blanks(buf);

	if (strncasecmp(cause, "Q.850", 5) || !(cause = strstr(cause, "cause="))) {
		return;
	}

	/* If text is present get rid of it */
	if ((text = strstr(cause, ";"))) {
		*text = '\0';
	}

	if (sscanf(cause, "cause=%30d", &code) != 1) {
		return;
	}

	ast_channel_hangupcause_set(session->channel, code & 0x7f);
}
/*!
 * \internal \brief The cURL header callback function
 */
static size_t curl_header_callback(char *buffer, size_t size, size_t nitems, void *data)
{
	struct curl_bucket_file_data *cb_data = data;
	size_t realsize;
	char *value;
	char *header;

	realsize = size * nitems;

	if (realsize > MAX_HEADER_LENGTH) {
		ast_log(LOG_WARNING, "cURL header length of '%zu' is too large: max %d\n",
			realsize, MAX_HEADER_LENGTH);
		return 0;
	}

	/* buffer may not be NULL terminated */
	header = ast_alloca(realsize + 1);
	memcpy(header, buffer, realsize);
	header[realsize] = '\0';
	value = strchr(header, ':');
	if (!value) {
		/* Not a header we care about; bail */
		return realsize;
	}
	*value++ = '\0';

	if (strcasecmp(header, "ETag")
		&& strcasecmp(header, "Cache-Control")
		&& strcasecmp(header, "Last-Modified")
		&& strcasecmp(header, "Content-Type")
		&& strcasecmp(header, "Expires")) {
		return realsize;
	}

	value = ast_trim_blanks(ast_skip_blanks(value));
	header = ast_str_to_lower(header);

	ast_bucket_file_metadata_set(cb_data->bucket_file, header, value);

	return realsize;
}
Beispiel #6
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;
}
static int dtmf_info_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
{
	pjsip_msg_body *body = rdata->msg_info.msg->body;
	char buf[body ? body->len : 0];
	char *cur = buf;
	char *line;

	char event = '\0';
	unsigned int duration = 100;

	char is_dtmf = is_media_type(rdata, "dtmf");

	if (!is_dtmf && !is_media_type(rdata, "dtmf-relay")) {
		return 0;
	}

	if (!body || !body->len) {
		/* need to return 200 OK on empty body */
		send_response(session, rdata, 200);
		return 0;
	}

	body->print_body(body, buf, body->len);

	if (is_dtmf) {
		/* directly use what is in the message body */
		event = get_event(cur);
	} else { /* content type = application/dtmf-relay */
		while ((line = strsep(&cur, "\r\n"))) {
			char *c;

			if (!(c = strchr(line, '='))) {
				continue;
			}

			*c++ = '\0';
			c = ast_skip_blanks(c);

			if (!strcasecmp(line, "signal")) {
				if (!(event = get_event(c))) {
					break;
				}
			} else if (!strcasecmp(line, "duration")) {
				sscanf(c, "%30u", &duration);
			}
		}
	}

	if (event == '!') {
		struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
		ast_queue_frame(session->channel, &f);
	} else if (event != '\0') {
		struct ast_frame f = { AST_FRAME_DTMF, };
		f.len = duration;
		f.subclass.integer = event;
		ast_queue_frame(session->channel, &f);
	} else {
		ast_log(LOG_ERROR, "Invalid DTMF event signal in INFO message.\n");
	}

	send_response(session, rdata, event ? 200 : 500);
	return event ? 0 : -1;
}