|
|
|
@ -2138,47 +2138,65 @@ static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittyp
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! \brief Locate closing quote in a string, skipping escaped quotes.
|
|
|
|
|
* optionally with a limit on the search.
|
|
|
|
|
* start must be past the first quote.
|
|
|
|
|
*/
|
|
|
|
|
static const char *find_closing_quote(const char *start, const char *lim)
|
|
|
|
|
{
|
|
|
|
|
char last_char = '\0';
|
|
|
|
|
const char *s;
|
|
|
|
|
for (s = start; *s && s != lim; last_char = *s++) {
|
|
|
|
|
if (*s == '"' && last_char != '\\')
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! \brief Pick out text in brackets from character string
|
|
|
|
|
\return pointer to terminated stripped string
|
|
|
|
|
\param tmp input string that will be modified */
|
|
|
|
|
\param tmp input string that will be modified
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
|
|
"foo" <bar> valid input, returns bar
|
|
|
|
|
foo returns the whole string
|
|
|
|
|
< "foo ... > returns the string between brackets
|
|
|
|
|
< "foo... bogus (missing closing bracket), returns the whole string
|
|
|
|
|
XXX maybe should still skip the opening bracket
|
|
|
|
|
*/
|
|
|
|
|
static char *get_in_brackets(char *tmp)
|
|
|
|
|
{
|
|
|
|
|
char *parse;
|
|
|
|
|
char *first_quote;
|
|
|
|
|
const char *parse = tmp;
|
|
|
|
|
char *first_bracket;
|
|
|
|
|
char *second_bracket;
|
|
|
|
|
char last_char;
|
|
|
|
|
|
|
|
|
|
parse = tmp;
|
|
|
|
|
for (;;) {
|
|
|
|
|
first_quote = strchr(parse, '"');
|
|
|
|
|
first_bracket = strchr(parse, '<');
|
|
|
|
|
if (first_quote && first_bracket && (first_quote < first_bracket)) {
|
|
|
|
|
last_char = '\0';
|
|
|
|
|
for (parse = first_quote + 1; *parse; parse++) {
|
|
|
|
|
if ((*parse == '"') && (last_char != '\\'))
|
|
|
|
|
break;
|
|
|
|
|
last_char = *parse;
|
|
|
|
|
}
|
|
|
|
|
if (!*parse) {
|
|
|
|
|
ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
parse++;
|
|
|
|
|
continue;
|
|
|
|
|
/*
|
|
|
|
|
* Skip any quoted text until we find the part in brackets.
|
|
|
|
|
* On any error give up and return the full string.
|
|
|
|
|
*/
|
|
|
|
|
while ( (first_bracket = strchr(parse, '<')) ) {
|
|
|
|
|
char *first_quote = strchr(parse, '"');
|
|
|
|
|
|
|
|
|
|
if (!first_quote || first_quote > first_bracket)
|
|
|
|
|
break; /* no need to look at quoted part */
|
|
|
|
|
/* the bracket is within quotes, so ignore it */
|
|
|
|
|
parse = find_closing_quote(first_quote + 1, NULL);
|
|
|
|
|
if (!*parse) { /* not found, return full string ? */
|
|
|
|
|
/* XXX or be robust and return in-bracket part ? */
|
|
|
|
|
ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (first_bracket) {
|
|
|
|
|
second_bracket = strchr(first_bracket + 1, '>');
|
|
|
|
|
if (second_bracket) {
|
|
|
|
|
*second_bracket = '\0';
|
|
|
|
|
return first_bracket + 1;
|
|
|
|
|
} else {
|
|
|
|
|
ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
parse++;
|
|
|
|
|
}
|
|
|
|
|
if (first_bracket) {
|
|
|
|
|
char *second_bracket = strchr(first_bracket + 1, '>');
|
|
|
|
|
if (second_bracket) {
|
|
|
|
|
*second_bracket = '\0';
|
|
|
|
|
tmp = first_bracket + 1;
|
|
|
|
|
} else {
|
|
|
|
|
ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
|
|
|
|
|
}
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! \brief Send SIP MESSAGE text within a call
|
|
|
|
|