Sat Mar 24 23:28:37 2007

Asterisk developer's documentation


enum.c File Reference

ENUM Support for Asterisk. More...

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <regex.h>
#include <unistd.h>
#include <errno.h>
#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/enum.h"
#include "asterisk/dns.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"

Include dependency graph for enum.c:

Go to the source code of this file.

Data Structures

struct  enum_context
struct  enum_naptr_rr
struct  enum_search
struct  naptr

Defines

#define ENUMLOOKUP_OPTIONS_COUNT   1
#define TOPLEV   "e164.arpa."

Functions

int ast_enum_init (void)
int ast_enum_reload (void)
int ast_get_enum (struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char *suffix, char *options)
 Lookup entry in ENUM Returns 1 if found, 0 if not found, -1 on hangup.
int ast_get_txt (struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char *txt, int txtlen)
 Lookup DNS TXT record (used by app TXTCIDnum.
 AST_MUTEX_DEFINE_STATIC (enumlock)
static int enum_callback (void *context, char *answer, int len, char *fullanswer)
static struct enum_searchenum_newtoplev (char *s)
static int parse_ie (char *data, int maxdatalen, char *src, int srclen)
static int parse_naptr (char *dst, int dstsize, char *tech, int techsize, char *answer, int len, char *naptrinput)
static int txt_callback (void *context, char *answer, int len, char *fullanswer)

Variables

naptr __packed__
static int enumver = 0
static struct enum_searchtoplevs


Detailed Description

ENUM Support for Asterisk.

Definition in file enum.c.


Define Documentation

#define ENUMLOOKUP_OPTIONS_COUNT   1
 

Definition at line 286 of file enum.c.

Referenced by ast_get_enum(), and enum_callback().

#define TOPLEV   "e164.arpa."
 

Definition at line 65 of file enum.c.

Referenced by ast_enum_init().


Function Documentation

int ast_enum_init void   ) 
 

Definition at line 622 of file enum.c.

References ast_config_destroy(), ast_config_load(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), cfg, enum_newtoplev(), free, ast_variable::name, ast_variable::next, s, TOPLEV, toplevs, and ast_variable::value.

Referenced by ast_enum_reload().

00623 {
00624    struct ast_config *cfg;
00625    struct enum_search *s, *sl;
00626    struct ast_variable *v;
00627 
00628    /* Destroy existing list */
00629    ast_mutex_lock(&enumlock);
00630    s = toplevs;
00631    while(s) {
00632       sl = s;
00633       s = s->next;
00634       free(sl);
00635    }
00636    toplevs = NULL;
00637    cfg = ast_config_load("enum.conf");
00638    if (cfg) {
00639       sl = NULL;
00640       v = ast_variable_browse(cfg, "general");
00641       while(v) {
00642          if (!strcasecmp(v->name, "search")) {
00643             s = enum_newtoplev(v->value);
00644             if (s) {
00645                if (sl)
00646                   sl->next = s;
00647                else
00648                   toplevs = s;
00649                sl = s;
00650             }
00651          }
00652          v = v->next;
00653       }
00654       ast_config_destroy(cfg);
00655    } else {
00656       toplevs = enum_newtoplev(TOPLEV);
00657    }
00658    enumver++;
00659    ast_mutex_unlock(&enumlock);
00660    return 0;
00661 }

int ast_enum_reload void   ) 
 

Definition at line 663 of file enum.c.

References ast_enum_init().

Referenced by ast_module_reload().

00664 {
00665    return ast_enum_init();
00666 }

int ast_get_enum struct ast_channel chan,
const char *  number,
char *  location,
int  maxloc,
char *  technology,
int  maxtech,
char *  suffix,
char *  options
 

Lookup entry in ENUM Returns 1 if found, 0 if not found, -1 on hangup.

Parameters:
chan Channel
number E164 number with or without the leading +
location Number returned (or SIP uri)
maxloc Max length
technology Technology (from url scheme in response) You can set it to get particular answer RR, if there are many techs in DNS response, example: "sip" If you need any record, then set it to empty string
maxtech Max length
suffix Zone suffix (if is NULL then use enum.conf 'search' variable)
options Options ('c' to count number of NAPTR RR, or number - the position of required RR in the answer list

Definition at line 384 of file enum.c.

References ast_autoservice_start(), ast_mutex_lock(), context, ENUMLOOKUP_OPTIONS_COUNT, enum_context::naptrinput, s, and toplevs.

Referenced by enumlookup_exec(), and function_enum().

00385 {
00386    struct enum_context context;
00387    char tmp[259 + 512];
00388    char naptrinput[512];
00389    int pos = strlen(number) - 1;
00390    int newpos = 0;
00391    int ret = -1;
00392    struct enum_search *s = NULL;
00393    int version = -1;
00394    /* for ISN rewrite */
00395    char *p1 = NULL;
00396    char *p2 = NULL;
00397    int k = 0;
00398    int i = 0;
00399    int z = 0;
00400 
00401    if (number[0] == 'n') {
00402       strncpy(naptrinput, number+1, sizeof(naptrinput));
00403    } else {
00404       strncpy(naptrinput, number, sizeof(naptrinput));
00405    }
00406 
00407    context.naptrinput = naptrinput; /* The number */
00408    context.dst = dst;         /* Return string */
00409    context.dstlen = dstlen;
00410    context.tech = tech;
00411    context.techlen = techlen;
00412    context.options = 0;
00413    context.position = 1;
00414    context.naptr_rrs = NULL;
00415    context.naptr_rrs_count = 0;
00416 
00417    if (options != NULL){
00418       if (*options == 'c'){
00419          context.options = ENUMLOOKUP_OPTIONS_COUNT;
00420          context.position = 0;
00421       } else {
00422          context.position = atoi(options);
00423          if (context.position < 1)
00424             context.position = 1;
00425       }
00426    }
00427 
00428    if (pos > 128)
00429       pos = 128;
00430 
00431    /* ISN rewrite */
00432    p1 = strchr(number, '*');
00433 
00434    if (number[0] == 'n') { /* do not perform ISN rewrite ('n' is testing flag) */
00435       p1 = NULL;
00436       k = 1; /* strip 'n' from number */
00437    }
00438 
00439    if (p1 != NULL) {
00440       p2 = p1+1;
00441       while (p1 > number){
00442          p1--;
00443          tmp[newpos++] = *p1;
00444          tmp[newpos++] = '.';
00445       }
00446       if (*p2) {
00447          while(*p2 && newpos < 128){
00448             tmp[newpos++] = *p2;
00449             p2++;
00450          }
00451          tmp[newpos++] = '.';
00452       }
00453 
00454    } else {
00455       while (pos >= k) {
00456          if (isdigit(number[pos])) {
00457             tmp[newpos++] = number[pos];
00458             tmp[newpos++] = '.';
00459          }
00460          pos--;
00461       }
00462    }
00463 
00464    if (chan && ast_autoservice_start(chan) < 0)
00465       return -1;
00466 
00467    for (;;) {
00468       ast_mutex_lock(&enumlock);
00469       if (version != enumver) {
00470          /* Ooh, a reload... */
00471          s = toplevs;
00472          version = enumver;
00473       } else {
00474          s = s->next;
00475       }
00476       if (suffix != NULL) {
00477          strncpy(tmp + newpos, suffix, sizeof(tmp) - newpos - 1);
00478       } else if (s) {
00479          strncpy(tmp + newpos, s->toplev, sizeof(tmp) - newpos - 1);
00480       }
00481       ast_mutex_unlock(&enumlock);
00482       if (!s)
00483          break;
00484       ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback);
00485       if (ret > 0)
00486          break;
00487       if (suffix != NULL)
00488                        break;
00489    }
00490    if (ret < 0) {
00491       ast_log(LOG_DEBUG, "No such number found: %s (%s)\n", tmp, strerror(errno));
00492       ret = 0;
00493    }
00494 
00495        if (context.naptr_rrs_count >= context.position && ! (context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
00496                /* sort array by NAPTR order/preference */
00497                for (k=0; k<context.naptr_rrs_count; k++) {
00498                        for (i=0; i<context.naptr_rrs_count; i++) {
00499                                /* use order first and then preference to compare */
00500                                if ((ntohs(context.naptr_rrs[k].naptr.order) < ntohs(context.naptr_rrs[i].naptr.order)
00501                                                && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
00502                                        || (ntohs(context.naptr_rrs[k].naptr.order) > ntohs(context.naptr_rrs[i].naptr.order)
00503                                                && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
00504                                        z = context.naptr_rrs[k].sort_pos;
00505                                        context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
00506                                        context.naptr_rrs[i].sort_pos = z;
00507                                        continue;
00508                                }
00509                                if (ntohs(context.naptr_rrs[k].naptr.order) == ntohs(context.naptr_rrs[i].naptr.order)) {
00510                                        if ((ntohs(context.naptr_rrs[k].naptr.pref) < ntohs(context.naptr_rrs[i].naptr.pref)
00511                                                        && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
00512                                                || (ntohs(context.naptr_rrs[k].naptr.pref) > ntohs(context.naptr_rrs[i].naptr.pref)
00513                                                        && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
00514                                                z = context.naptr_rrs[k].sort_pos;
00515                                                context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
00516                                                context.naptr_rrs[i].sort_pos = z;
00517                                        }
00518                                }
00519                        }
00520                }
00521                for (k=0; k<context.naptr_rrs_count; k++) {
00522                        if (context.naptr_rrs[k].sort_pos == context.position-1) {
00523                                ast_copy_string(context.dst, context.naptr_rrs[k].result, dstlen);
00524                                ast_copy_string(context.tech, context.naptr_rrs[k].tech, techlen);
00525                                break;
00526                        }
00527                }
00528        } else if (!(context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
00529                context.dst[0] = 0;
00530        }
00531 
00532    if (chan)
00533       ret |= ast_autoservice_stop(chan);
00534 
00535    for (k=0; k<context.naptr_rrs_count; k++) {
00536       free(context.naptr_rrs[k].result);
00537       free(context.naptr_rrs[k].tech);
00538    }
00539 
00540    free(context.naptr_rrs);
00541 
00542    return ret;
00543 }

int ast_get_txt struct ast_channel chan,
const char *  number,
char *  location,
int  maxloc,
char *  technology,
int  maxtech,
char *  txt,
int  maxtxt
 

Lookup DNS TXT record (used by app TXTCIDnum.

Parameters:
chan Channel
number E164 number with or without the leading +
location Number returned (or SIP uri)
maxloc Max length of number
technology Technology (not used in TXT records)
maxtech Max length
txt Text string (return value)
maxtxt Max length of "txt"

Definition at line 548 of file enum.c.

References ast_autoservice_start(), ast_mutex_lock(), context, enum_context::naptrinput, s, and toplevs.

Referenced by function_txtcidname(), and txtcidname_exec().

00549 {
00550    struct enum_context context;
00551    char tmp[259 + 512];
00552    char naptrinput[512] = "+";
00553    int pos = strlen(number) - 1;
00554    int newpos = 0;
00555    int ret = -1;
00556    struct enum_search *s = NULL;
00557    int version = -1;
00558 
00559    strncat(naptrinput, number, sizeof(naptrinput) - 2);
00560 
00561    context.naptrinput = naptrinput;
00562    context.dst = dst;
00563    context.dstlen = dstlen;
00564    context.tech = tech;
00565    context.techlen = techlen;
00566    context.txt = txt;
00567    context.txtlen = txtlen;
00568 
00569    if (pos > 128)
00570       pos = 128;
00571    while (pos >= 0) {
00572       tmp[newpos++] = number[pos--];
00573       tmp[newpos++] = '.';
00574    }
00575 
00576    if (chan && ast_autoservice_start(chan) < 0)
00577       return -1;
00578 
00579    for (;;) {
00580       ast_mutex_lock(&enumlock);
00581       if (version != enumver) {
00582          /* Ooh, a reload... */
00583          s = toplevs;
00584          version = enumver;
00585       } else {
00586          s = s->next;
00587       }
00588       if (s) {
00589          strncpy(tmp + newpos, s->toplev, sizeof(tmp) - newpos - 1);
00590       }
00591       ast_mutex_unlock(&enumlock);
00592       if (!s)
00593          break;
00594 
00595       ret = ast_search_dns(&context, tmp, C_IN, T_TXT, txt_callback);
00596       if (ret > 0)
00597          break;
00598    }
00599    if (ret < 0) {
00600       ast_log(LOG_DEBUG, "No such number found: %s (%s)\n", tmp, strerror(errno));
00601       ret = 0;
00602    }
00603    if (chan)
00604       ret |= ast_autoservice_stop(chan);
00605    return ret;
00606 }

AST_MUTEX_DEFINE_STATIC enumlock   ) 
 

static int enum_callback void *  context,
char *  answer,
int  len,
char *  fullanswer
[static]
 

Definition at line 345 of file enum.c.

References ast_log(), ast_strlen_zero(), enum_context::dst, enum_context::dstlen, ENUMLOOKUP_OPTIONS_COUNT, LOG_WARNING, enum_context::naptr_rrs, enum_context::naptr_rrs_count, enum_context::naptrinput, enum_context::options, parse_naptr(), enum_context::position, realloc, enum_naptr_rr::result, enum_naptr_rr::sort_pos, strdup, enum_naptr_rr::tech, enum_context::tech, and enum_context::techlen.

00346 {
00347    struct enum_context *c = (struct enum_context *)context;
00348        void *p = NULL;
00349        int res;
00350 
00351        res = parse_naptr(c->dst, c->dstlen, c->tech, c->techlen, answer, len, c->naptrinput);
00352 
00353        if (res < 0) {
00354       ast_log(LOG_WARNING, "Failed to parse naptr :(\n");
00355       return -1;
00356        } else if (res > 0 && !ast_strlen_zero(c->dst)){ /* ok, we got needed NAPTR */
00357                if (c->options & ENUMLOOKUP_OPTIONS_COUNT){ /* counting RRs */
00358                        c->position++;
00359                        snprintf(c->dst, c->dstlen, "%d", c->position);
00360                } else  {
00361                        p = realloc(c->naptr_rrs, sizeof(struct enum_naptr_rr)*(c->naptr_rrs_count+1));
00362                        if (p) {
00363                                c->naptr_rrs = (struct enum_naptr_rr*)p;
00364                                memcpy(&c->naptr_rrs[c->naptr_rrs_count].naptr, answer, sizeof(struct naptr));
00365                                /* printf("order=%d, pref=%d\n", ntohs(c->naptr_rrs[c->naptr_rrs_count].naptr.order), ntohs(c->naptr_rrs[c->naptr_rrs_count].naptr.pref)); */
00366                                c->naptr_rrs[c->naptr_rrs_count].result = strdup(c->dst);
00367                                c->naptr_rrs[c->naptr_rrs_count].tech = strdup(c->tech);
00368                                c->naptr_rrs[c->naptr_rrs_count].sort_pos = c->naptr_rrs_count;
00369                                c->naptr_rrs_count++;
00370                        }
00371                        c->dst[0] = 0;
00372                }
00373                return 0;
00374    }
00375 
00376        if (c->options & ENUMLOOKUP_OPTIONS_COUNT)  { /* counting RRs */
00377                snprintf(c->dst, c->dstlen, "%d", c->position);
00378        }
00379 
00380    return 0;
00381 }

static struct enum_search* enum_newtoplev char *  s  )  [static]
 

Definition at line 609 of file enum.c.

References malloc.

Referenced by ast_enum_init().

00610 {
00611    struct enum_search *tmp;
00612 
00613    tmp = malloc(sizeof(struct enum_search));
00614    if (tmp) {
00615       memset(tmp, 0, sizeof(struct enum_search));
00616       ast_copy_string(tmp->toplev, s, sizeof(tmp->toplev));
00617    }
00618    return tmp;
00619 }

static int parse_ie char *  data,
int  maxdatalen,
char *  src,
int  srclen
[static]
 

Definition at line 83 of file enum.c.

References ast_log(), and LOG_WARNING.

Referenced by parse_naptr().

00084 {
00085    int len, olen;
00086 
00087    len = olen = (int)src[0];
00088    src++;
00089    srclen--;
00090    if (len > srclen || len < 0 ) {
00091       ast_log(LOG_WARNING, "ENUM parsing failed: Wanted %d characters, got %d\n", len, srclen);
00092       return -1;
00093    }
00094    if (len > maxdatalen)
00095       len = maxdatalen;
00096    memcpy(data, src, len);
00097    return olen + 1;
00098 }

static int parse_naptr char *  dst,
int  dstsize,
char *  tech,
int  techsize,
char *  answer,
int  len,
char *  naptrinput
[static]
 

Definition at line 101 of file enum.c.

References ast_log(), LOG_DEBUG, LOG_WARNING, option_debug, and parse_ie().

Referenced by enum_callback().

00102 {
00103 
00104    char tech_return[80];
00105    char *oanswer = answer;
00106    char flags[512] = "";
00107    char services[512] = "";
00108    char *p;
00109    char regexp[512] = "";
00110    char repl[512] = "";
00111    char temp[512] = "";
00112    char delim;
00113    char *delim2;
00114    char *pattern, *subst, *d;
00115    int res;
00116    int regexp_len, size, backref;
00117    int d_len = sizeof(temp) - 1;
00118    regex_t preg;
00119    regmatch_t pmatch[9];
00120 
00121    tech_return[0] = '\0';
00122 
00123    dst[0] = '\0';
00124 
00125    if (len < sizeof(struct naptr)) {
00126       ast_log(LOG_WARNING, "NAPTR record length too short\n");
00127       return -1;
00128    }
00129    answer += sizeof(struct naptr);
00130    len -= sizeof(struct naptr);
00131    if ((res = parse_ie(flags, sizeof(flags) - 1, answer, len)) < 0) {
00132       ast_log(LOG_WARNING, "Failed to get flags from NAPTR record\n");
00133       return -1;
00134    } else {
00135       answer += res;
00136       len -= res;
00137    }
00138    if ((res = parse_ie(services, sizeof(services) - 1, answer, len)) < 0) {
00139       ast_log(LOG_WARNING, "Failed to get services from NAPTR record\n");
00140       return -1;
00141    } else {
00142       answer += res;
00143       len -= res;
00144    }
00145    if ((res = parse_ie(regexp, sizeof(regexp) - 1, answer, len)) < 0) {
00146       ast_log(LOG_WARNING, "Failed to get regexp from NAPTR record\n");
00147       return -1;
00148    } else {
00149       answer += res;
00150       len -= res;
00151    }
00152 
00153    if ((res = dn_expand((unsigned char *)oanswer, (unsigned char *)answer + len, (unsigned char *)answer, repl, sizeof(repl) - 1)) < 0) {
00154       ast_log(LOG_WARNING, "Failed to expand hostname\n");
00155       return -1;
00156    }
00157 
00158    if (option_debug > 2)   /* Advanced NAPTR debugging */
00159       ast_log(LOG_DEBUG, "NAPTR input='%s', flags='%s', services='%s', regexp='%s', repl='%s'\n",
00160          naptrinput, flags, services, regexp, repl);
00161 
00162    if (tolower(flags[0]) != 'u') {
00163       ast_log(LOG_WARNING, "NAPTR Flag must be 'U' or 'u'.\n");
00164       return -1;
00165    }
00166 
00167    p = strstr(services, "e2u+");
00168    if (p == NULL)
00169       p = strstr(services, "E2U+");
00170    if (p){
00171       p = p + 4;
00172       if (strchr(p, ':')){
00173          p = strchr(p, ':') + 1;
00174       }
00175       ast_copy_string(tech_return, p, sizeof(tech_return));
00176    } else {
00177 
00178       p = strstr(services, "+e2u");
00179       if (p == NULL)
00180          p = strstr(services, "+E2U");
00181       if (p) {
00182          *p = 0;
00183          p = strchr(services, ':');
00184          if (p)
00185             *p = 0;
00186          ast_copy_string(tech_return, services, sizeof(tech_return));
00187       }
00188    }
00189 
00190    /* DEDBUGGING STUB
00191    ast_copy_string(regexp, "!^\\+43(.*)$!\\1@bla.fasel!", sizeof(regexp) - 1);
00192    */
00193 
00194    regexp_len = strlen(regexp);
00195    if (regexp_len < 7) {
00196       ast_log(LOG_WARNING, "Regex too short to be meaningful.\n");
00197       return -1;
00198    }
00199 
00200 
00201    delim = regexp[0];
00202    delim2 = strchr(regexp + 1, delim);
00203    if ((delim2 == NULL) || (regexp[regexp_len-1] != delim)) {
00204       ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n",regexp);
00205       return -1;
00206    }
00207 
00208    pattern = regexp + 1;
00209    *delim2 = 0;
00210    subst   = delim2 + 1;
00211    regexp[regexp_len-1] = 0;
00212 
00213 #if 0
00214    printf("Pattern: %s\n", pattern);
00215    printf("Subst: %s\n", subst);
00216        printf("Input: %s\n", naptrinput);
00217 #endif
00218 
00219 /*
00220  * now do the regex wizardry.
00221  */
00222 
00223    if (regcomp(&preg, pattern, REG_EXTENDED | REG_NEWLINE)) {
00224       ast_log(LOG_WARNING, "NAPTR Regex compilation error (regex = \"%s\").\n",regexp);
00225       return -1;
00226    }
00227 
00228    if (preg.re_nsub > 9) {
00229       ast_log(LOG_WARNING, "NAPTR Regex compilation error: too many subs.\n");
00230       regfree(&preg);
00231       return -1;
00232    }
00233 
00234    if (regexec(&preg, naptrinput, 9, pmatch, 0)) {
00235       ast_log(LOG_WARNING, "NAPTR Regex match failed.\n");
00236       regfree(&preg);
00237       return -1;
00238    }
00239    regfree(&preg);
00240 
00241    d = temp;
00242    d_len--;
00243    while (*subst && (d_len > 0)) {
00244       if ((subst[0] == '\\') && isdigit(subst[1]) && (pmatch[subst[1]-'0'].rm_so != -1)) {
00245          backref = subst[1]-'0';
00246          size = pmatch[backref].rm_eo - pmatch[backref].rm_so;
00247          if (size > d_len) {
00248             ast_log(LOG_WARNING, "Not enough space during NAPTR regex substitution.\n");
00249             return -1;
00250             }
00251          memcpy(d, naptrinput + pmatch[backref].rm_so, size);
00252          d += size;
00253          d_len -= size;
00254          subst += 2;
00255       } else if (isprint(*subst)) {
00256          *d++ = *subst++;
00257          d_len--;
00258       } else {
00259          ast_log(LOG_WARNING, "Error during regex substitution.\n");
00260          return -1;
00261       }
00262    }
00263    *d = 0;
00264    ast_copy_string(dst, temp, dstsize);
00265    dst[dstsize - 1] = '\0';
00266 
00267    if (*tech != '\0'){ /* check if it is requested NAPTR */
00268       if (!strncasecmp(tech, "ALL", techsize)){
00269          return 1; /* return or count any RR */
00270       }
00271       if (!strncasecmp(tech_return, tech, sizeof(tech_return)<techsize?sizeof(tech_return):techsize)){
00272          ast_copy_string(tech, tech_return, techsize);
00273          return 1; /* we got out RR */
00274       } else { /* go to the next RR in the DNS answer */
00275          return 0;
00276       }
00277    }
00278 
00279    /* tech was not specified, return first parsed RR */
00280    ast_copy_string(tech, tech_return, techsize);
00281 
00282    return 1;
00283 }

static int txt_callback void *  context,
char *  answer,
int  len,
char *  fullanswer
[static]
 

Definition at line 310 of file enum.c.

References enum_context::txt, and enum_context::txtlen.

00311 {
00312    struct enum_context *c = (struct enum_context *)context;
00313 #if 0
00314    printf("ENUMTXT Called\n");
00315 #endif
00316 
00317    if (answer == NULL) {
00318       c->txt = NULL;
00319       c->txtlen = 0;
00320       return 0;
00321    }
00322 
00323    /* skip over first byte, as for some reason it's a vertical tab character */
00324    answer += 1;
00325    len -= 1;
00326 
00327    /* answer is not null-terminated, but should be */
00328        /* this is safe to do, as answer has extra bytes on the end we can
00329            safely overwrite with a null */
00330    answer[len] = '\0';
00331    /* now increment len so that len includes the null, so that we can
00332       compare apples to apples */
00333    len +=1;
00334 
00335    /* finally, copy the answer into c->txt */
00336    ast_copy_string(c->txt, answer, len < c->txtlen ? len : (c->txtlen));
00337 
00338    /* just to be safe, let's make sure c->txt is null terminated */
00339    c->txt[(c->txtlen)-1] = '\0';
00340 
00341    return 1;
00342 }


Variable Documentation

struct naptr __packed__
 

int enumver = 0 [static]
 

Definition at line 73 of file enum.c.

struct enum_search * toplevs [static]
 

Referenced by ast_enum_init(), ast_get_enum(), and ast_get_txt().


Generated on Sat Mar 24 23:28:38 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6