diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-04-28 13:53:01 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-04-28 13:53:01 +0000 |
commit | 530fca2223e609d98029ea9052dd1de98afbc562 (patch) | |
tree | 0a40b7a4b62a0c4908ae4b9042c0a2d4f864dc6f /asterisk.c | |
parent | b56ba714346f59b0718d1cf1c6fa427232a6a5be (diff) |
Provide gethostbyname_r emulation for FreeBSD and fix zap call to setstate to include callerid (bug #1411, #1498)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@2793 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'asterisk.c')
-rwxr-xr-x | asterisk.c | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/asterisk.c b/asterisk.c index 56dcc0d09..449c1ddcd 100755 --- a/asterisk.c +++ b/asterisk.c @@ -48,6 +48,10 @@ #include "asterisk.h" #include <asterisk/config.h> +#if defined(__FreeBSD__) +#include <netdb.h> +#endif + #define AST_MAX_CONNECTS 128 #define NUM_MSGS 64 @@ -1675,13 +1679,133 @@ int main(int argc, char *argv[]) return 0; } + +#if defined(__FreeBSD__) + +/* duh? ERANGE value copied from web... */ +#define ERANGE 34 +#undef gethostbyname + +int gethostbyname_r (const char *name, + struct hostent *ret, + char *buf, + size_t buflen, + struct hostent **result, + int *h_errnop); + +int gethostbyname_r (const char *name, + struct hostent *ret, + char *buf, + size_t buflen, + struct hostent **result, + int *h_errnop) { + + int hsave; + struct hostent *ph; + static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_lock(&__mutex); /* begin critical area */ + hsave = h_errno; + + ph = gethostbyname(name); + *h_errnop = h_errno; /* copy h_errno to *h_herrnop */ + if (ph == NULL) { + *result = NULL; + } else { + char **p, **q; + char *pbuf; + int nbytes=0; + int naddr=0, naliases=0; + /* determine if we have enough space in buf */ + + /* count how many addresses */ + for (p = ph->h_addr_list; *p != 0; p++) { + nbytes += ph->h_length; /* addresses */ + nbytes += sizeof(*p); /* pointers */ + naddr++; + } + nbytes += sizeof(*p); /* one more for the terminating NULL */ + + /* count how many aliases, and total length of strings */ + + for (p = ph->h_aliases; *p != 0; p++) { + nbytes += (strlen(*p)+1); /* aliases */ + nbytes += sizeof(*p); /* pointers */ + naliases++; + } + nbytes += sizeof(*p); /* one more for the terminating NULL */ + + /* here nbytes is the number of bytes required in buffer */ + /* as a terminator must be there, the minimum value is ph->h_length */ + if(nbytes > buflen) { + *result = NULL; + pthread_mutex_unlock(&__mutex); /* end critical area */ + return ERANGE; /* not enough space in buf!! */ + } + + /* There is enough space. Now we need to do a deep copy! */ + /* Allocation in buffer: + from [0] to [(naddr-1) * sizeof(*p)]: + pointers to addresses + at [naddr * sizeof(*p)]: + NULL + from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] : + pointers to aliases + at [(naddr+naliases+1) * sizeof(*p)]: + NULL + then naddr addresses (fixed length), and naliases aliases (asciiz). + */ + + *ret = *ph; /* copy whole structure (not its address!) */ + + /* copy addresses */ + q = (char **)buf; /* pointer to pointers area (type: char **) */ + ret->h_addr_list = q; /* update pointer to address list */ + pbuf = buf + ((naddr+naliases+2)*sizeof(*p)); /* skip that area */ + for (p = ph->h_addr_list; *p != 0; p++) { + memcpy(pbuf, *p, ph->h_length); /* copy address bytes */ + *q++ = pbuf; /* the pointer is the one inside buf... */ + pbuf += ph->h_length; /* advance pbuf */ + } + *q++ = NULL; /* address list terminator */ + + /* copy aliases */ + + ret->h_aliases = q; /* update pointer to aliases list */ + for (p = ph->h_aliases; *p != 0; p++) { + strcpy(pbuf, *p); /* copy alias strings */ + *q++ = pbuf; /* the pointer is the one inside buf... */ + pbuf += strlen(*p); /* advance pbuf */ + *pbuf++ = 0; /* string terminator */ + } + *q++ = NULL; /* terminator */ + + strcpy(pbuf, ph->h_name); /* copy alias strings */ + ret->h_name = pbuf; + pbuf += strlen(ph->h_name); /* advance pbuf */ + *pbuf++ = 0; /* string terminator */ + + *result = ret; /* and let *result point to structure */ + + } + h_errno = hsave; /* restore h_errno */ + + pthread_mutex_unlock(&__mutex); /* end critical area */ + + return (*result == NULL); + +} + + +#endif + struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp) { int res; int herrno; struct hostent *result = NULL; - /* XXX Does BSD do this differently? XXX */ + res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno); + if (res) return NULL; return &hp->hp; |