summaryrefslogtreecommitdiff
path: root/main/enum.c
diff options
context:
space:
mode:
authorRussell Bryant <russell@russellbryant.com>2007-05-15 23:05:20 +0000
committerRussell Bryant <russell@russellbryant.com>2007-05-15 23:05:20 +0000
commite090c28540a4fc5498be124fcf97e960c0ffe2e7 (patch)
tree9e3df4c166ed813bce5ba2283285f0a32de6b1ac /main/enum.c
parentf02e26feffb1e36670a046d56fb9c66174b41c4a (diff)
Add two new dialplan functions: ENUMQUERY and ENUMRESULT. These functions
allow you to initiate an ENUM query using ENUMQUERY, and then access the details of all of the results using ENUMRESULT. Previously, if you wanted to access multiple results, Asterisk would have to do a new DNS lookup every time. (patch by bbryant) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@64480 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/enum.c')
-rw-r--r--main/enum.c127
1 files changed, 55 insertions, 72 deletions
diff --git a/main/enum.c b/main/enum.c
index 5db6adb01..140a38ff9 100644
--- a/main/enum.c
+++ b/main/enum.c
@@ -91,11 +91,6 @@ static int enumver;
AST_MUTEX_DEFINE_STATIC(enumlock);
-struct naptr {
- unsigned short order;
- unsigned short pref;
-} __attribute__ ((__packed__));
-
/*! \brief Parse NAPTR record information elements */
static unsigned int parse_ie(char *data, unsigned int maxdatalen, unsigned char *src, unsigned int srclen)
{
@@ -298,26 +293,6 @@ static int parse_naptr(char *dst, int dstsize, char *tech, int techsize, unsigne
/* do not return requested value, just count RRs and return thei number in dst */
#define ENUMLOOKUP_OPTIONS_COUNT 1
-struct enum_naptr_rr {
- struct naptr naptr; /* order and preference of RR */
- char *result; /* result of naptr parsing,e.g.: tel:+5553 */
- char *tech; /* Technology (from URL scheme) */
- int sort_pos; /* sort position */
-};
-
-struct enum_context {
- char *dst; /* Destination part of URL from ENUM */
- int dstlen; /* Length */
- char *tech; /* Technology (from URL scheme) */
- int techlen; /* Length */
- char *txt; /* TXT record in TXT lookup */
- int txtlen; /* Length */
- char *naptrinput; /* The number to lookup */
- int position; /* used as counter for RRs or specifies position of required RR */
- int options; /* options , see ENUMLOOKUP_OPTIONS_* defined above */
- struct enum_naptr_rr *naptr_rrs; /* array of parsed NAPTR RRs */
- int naptr_rrs_count; /* Size of array naptr_rrs */
-};
/*! \brief Callback for TXT record lookup */
static int txt_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
@@ -389,9 +364,9 @@ static int enum_callback(void *context, unsigned char *answer, int len, unsigned
}
/*! \brief ENUM lookup */
-int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char* suffix, char* options, unsigned int record)
+int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char* suffix, char* options, unsigned int record, struct enum_context **argcontext)
{
- struct enum_context context;
+ struct enum_context *context;
char tmp[259 + 512];
char naptrinput[512];
int pos = strlen(number) - 1;
@@ -406,27 +381,30 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds
int i = 0;
int z = 0;
+ if (!(context = ast_calloc(1, sizeof(*context))))
+ return -1;
+
ast_copy_string(naptrinput, number[0] == 'n' ? number+1 : number, sizeof(naptrinput));
- context.naptrinput = naptrinput; /* The number */
- context.dst = dst; /* Return string */
- context.dstlen = dstlen;
- context.tech = tech;
- context.techlen = techlen;
- context.options = 0;
- context.position = record;
- context.naptr_rrs = NULL;
- context.naptr_rrs_count = 0;
+ context->naptrinput = naptrinput; /* The number */
+ context->dst = dst; /* Return string */
+ context->dstlen = dstlen;
+ context->tech = tech;
+ context->techlen = techlen;
+ context->options = 0;
+ context->position = record;
+ context->naptr_rrs = NULL;
+ context->naptr_rrs_count = 0;
if (options != NULL) {
if (*options == 'c') {
- context.options = ENUMLOOKUP_OPTIONS_COUNT;
- context.position = 0;
+ context->options = ENUMLOOKUP_OPTIONS_COUNT;
+ context->position = 0;
}
}
ast_log(LOG_DEBUG, "ast_get_enum(): n='%s', tech='%s', suffix='%s', options='%d', record='%d'\n",
- number, tech, suffix, context.options, context.position);
+ number, tech, suffix, context->options, context->position);
if (pos > 128)
pos = 128;
@@ -464,12 +442,14 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds
}
}
- if (chan && ast_autoservice_start(chan) < 0)
+ if (chan && ast_autoservice_start(chan) < 0) {
+ free(context);
return -1;
+ }
- if(suffix) {
+ if (suffix) {
ast_copy_string(tmp + newpos, suffix, sizeof(tmp) - newpos);
- ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback);
+ ret = ast_search_dns(context, tmp, C_IN, T_NAPTR, enum_callback);
ast_log(LOG_DEBUG, "ast_get_enum: ast_search_dns(%s) returned %d\n", tmp, ret);
} else {
ret = -1; /* this is actually dead code since the demise of app_enum.c */
@@ -502,51 +482,54 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds
ret = 0;
}
- if (context.naptr_rrs_count >= context.position && ! (context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
+ if (context->naptr_rrs_count >= context->position && ! (context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
/* sort array by NAPTR order/preference */
- for (k = 0; k < context.naptr_rrs_count; k++) {
- for (i = 0; i < context.naptr_rrs_count; i++) {
+ for (k = 0; k < context->naptr_rrs_count; k++) {
+ for (i = 0; i < context->naptr_rrs_count; i++) {
/* use order first and then preference to compare */
- if ((ntohs(context.naptr_rrs[k].naptr.order) < ntohs(context.naptr_rrs[i].naptr.order)
- && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
- || (ntohs(context.naptr_rrs[k].naptr.order) > ntohs(context.naptr_rrs[i].naptr.order)
- && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
- z = context.naptr_rrs[k].sort_pos;
- context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
- context.naptr_rrs[i].sort_pos = z;
+ if ((ntohs(context->naptr_rrs[k].naptr.order) < ntohs(context->naptr_rrs[i].naptr.order)
+ && context->naptr_rrs[k].sort_pos > context->naptr_rrs[i].sort_pos)
+ || (ntohs(context->naptr_rrs[k].naptr.order) > ntohs(context->naptr_rrs[i].naptr.order)
+ && context->naptr_rrs[k].sort_pos < context->naptr_rrs[i].sort_pos)){
+ z = context->naptr_rrs[k].sort_pos;
+ context->naptr_rrs[k].sort_pos = context->naptr_rrs[i].sort_pos;
+ context->naptr_rrs[i].sort_pos = z;
continue;
}
- if (ntohs(context.naptr_rrs[k].naptr.order) == ntohs(context.naptr_rrs[i].naptr.order)) {
- if ((ntohs(context.naptr_rrs[k].naptr.pref) < ntohs(context.naptr_rrs[i].naptr.pref)
- && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
- || (ntohs(context.naptr_rrs[k].naptr.pref) > ntohs(context.naptr_rrs[i].naptr.pref)
- && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
- z = context.naptr_rrs[k].sort_pos;
- context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
- context.naptr_rrs[i].sort_pos = z;
+ if (ntohs(context->naptr_rrs[k].naptr.order) == ntohs(context->naptr_rrs[i].naptr.order)) {
+ if ((ntohs(context->naptr_rrs[k].naptr.pref) < ntohs(context->naptr_rrs[i].naptr.pref)
+ && context->naptr_rrs[k].sort_pos > context->naptr_rrs[i].sort_pos)
+ || (ntohs(context->naptr_rrs[k].naptr.pref) > ntohs(context->naptr_rrs[i].naptr.pref)
+ && context->naptr_rrs[k].sort_pos < context->naptr_rrs[i].sort_pos)){
+ z = context->naptr_rrs[k].sort_pos;
+ context->naptr_rrs[k].sort_pos = context->naptr_rrs[i].sort_pos;
+ context->naptr_rrs[i].sort_pos = z;
}
}
}
}
- for (k = 0; k < context.naptr_rrs_count; k++) {
- if (context.naptr_rrs[k].sort_pos == context.position-1) {
- ast_copy_string(context.dst, context.naptr_rrs[k].result, dstlen);
- ast_copy_string(context.tech, context.naptr_rrs[k].tech, techlen);
+ for (k = 0; k < context->naptr_rrs_count; k++) {
+ if (context->naptr_rrs[k].sort_pos == context->position-1) {
+ ast_copy_string(context->dst, context->naptr_rrs[k].result, dstlen);
+ ast_copy_string(context->tech, context->naptr_rrs[k].tech, techlen);
break;
}
}
- } else if (!(context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
- context.dst[0] = 0;
+ } else if (!(context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
+ context->dst[0] = 0;
}
if (chan)
ret |= ast_autoservice_stop(chan);
- for (k = 0; k < context.naptr_rrs_count; k++) {
- free(context.naptr_rrs[k].result);
- free(context.naptr_rrs[k].tech);
- }
-
- free(context.naptr_rrs);
+ if (!argcontext) {
+ for (k = 0; k < context->naptr_rrs_count; k++) {
+ free(context->naptr_rrs[k].result);
+ free(context->naptr_rrs[k].tech);
+ }
+ free(context->naptr_rrs);
+ free(context);
+ } else
+ *argcontext = context;
return ret;
}