00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include <ctype.h>
00013
#include <string.h>
00014
#include <unistd.h>
00015
#include <sys/types.h>
00016
#include <sys/socket.h>
00017
#include <netinet/in.h>
00018
#include <arpa/inet.h>
00019
#include <asterisk/lock.h>
00020
#include <asterisk/utils.h>
00021
00022
static char base64[64];
00023
static char b2a[256];
00024
00025
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
00026
00027
00028
#define ERANGE 34
00029
#undef gethostbyname
00030
00031
AST_MUTEX_DEFINE_STATIC(__mutex);
00032
00033
00034
static int gethostbyname_r (
const char *name,
struct hostent *ret,
char *buf,
00035 size_t buflen,
struct hostent **result,
00036
int *h_errnop)
00037 {
00038
int hsave;
00039
struct hostent *ph;
00040
ast_mutex_lock(&__mutex);
00041 hsave = h_errno;
00042
00043 ph =
gethostbyname(name);
00044 *h_errnop = h_errno;
00045
if (ph == NULL) {
00046 *result = NULL;
00047 }
else {
00048
char **p, **q;
00049
char *pbuf;
00050
int nbytes=0;
00051
int naddr=0, naliases=0;
00052
00053
00054
00055
for (p = ph->h_addr_list; *p != 0; p++) {
00056 nbytes += ph->h_length;
00057 nbytes +=
sizeof(*p);
00058 naddr++;
00059 }
00060 nbytes +=
sizeof(*p);
00061
00062
00063
for (p = ph->h_aliases; *p != 0; p++) {
00064 nbytes += (strlen(*p)+1);
00065 nbytes +=
sizeof(*p);
00066 naliases++;
00067 }
00068 nbytes +=
sizeof(*p);
00069
00070
00071
00072
if(nbytes > buflen) {
00073 *result = NULL;
00074
ast_mutex_unlock(&__mutex);
00075
return ERANGE;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 *ret = *ph;
00092
00093
00094 q = (
char **)buf;
00095 ret->h_addr_list = q;
00096 pbuf = buf + ((naddr+naliases+2)*
sizeof(*p));
00097
for (p = ph->h_addr_list; *p != 0; p++) {
00098 memcpy(pbuf, *p, ph->h_length);
00099 *q++ = pbuf;
00100 pbuf += ph->h_length;
00101 }
00102 *q++ = NULL;
00103
00104
00105 ret->h_aliases = q;
00106
for (p = ph->h_aliases; *p != 0; p++) {
00107 strcpy(pbuf, *p);
00108 *q++ = pbuf;
00109 pbuf += strlen(*p);
00110 *pbuf++ = 0;
00111 }
00112 *q++ = NULL;
00113
00114 strcpy(pbuf, ph->h_name);
00115 ret->h_name = pbuf;
00116 pbuf += strlen(ph->h_name);
00117 *pbuf++ = 0;
00118
00119 *result = ret;
00120
00121 }
00122 h_errno = hsave;
00123
ast_mutex_unlock(&__mutex);
00124
00125
return (*result == NULL);
00126 }
00127
00128
00129
#endif
00130
00131
00132
00133
00134 struct hostent *
ast_gethostbyname(
const char *host,
struct ast_hostent *hp)
00135 {
00136
int res;
00137
int herrno;
00138
const char *
s;
00139
struct hostent *result = NULL;
00140
00141
00142
00143
00144
s = host;
00145
while(
s && *
s) {
00146
if (!isdigit(*
s))
00147
break;
00148
s++;
00149 }
00150
if (!
s || !*
s)
00151
return NULL;
00152 res = gethostbyname_r(host, &hp->
hp, hp->
buf,
sizeof(hp->
buf), &result, &herrno);
00153
00154
if (res || !result || !hp->
hp.h_addr_list || !hp->
hp.h_addr_list[0])
00155
return NULL;
00156
return &hp->
hp;
00157 }
00158
00159
00160
00161
00162
00163
00164
AST_MUTEX_DEFINE_STATIC(test_lock);
00165
AST_MUTEX_DEFINE_STATIC(test_lock2);
00166
static pthread_t test_thread;
00167
static int lock_count = 0;
00168
static int test_errors = 0;
00169
00170
static void *test_thread_body(
void *data)
00171 {
00172
ast_mutex_lock(&test_lock);
00173 lock_count += 10;
00174
if (lock_count != 10)
00175 test_errors++;
00176
ast_mutex_lock(&test_lock);
00177 lock_count += 10;
00178
if (lock_count != 20)
00179 test_errors++;
00180
ast_mutex_lock(&test_lock2);
00181
ast_mutex_unlock(&test_lock);
00182 lock_count -= 10;
00183
if (lock_count != 10)
00184 test_errors++;
00185
ast_mutex_unlock(&test_lock);
00186 lock_count -= 10;
00187
ast_mutex_unlock(&test_lock2);
00188
if (lock_count != 0)
00189 test_errors++;
00190
return NULL;
00191 }
00192
00193 int test_for_thread_safety(
void)
00194 {
00195
ast_mutex_lock(&test_lock2);
00196
ast_mutex_lock(&test_lock);
00197 lock_count += 1;
00198
ast_mutex_lock(&test_lock);
00199 lock_count += 1;
00200 pthread_create(&test_thread, NULL, test_thread_body, NULL);
00201 usleep(100);
00202
if (lock_count != 2)
00203 test_errors++;
00204
ast_mutex_unlock(&test_lock);
00205 lock_count -= 1;
00206 usleep(100);
00207
if (lock_count != 1)
00208 test_errors++;
00209
ast_mutex_unlock(&test_lock);
00210 lock_count -= 1;
00211
if (lock_count != 0)
00212 test_errors++;
00213
ast_mutex_unlock(&test_lock2);
00214 usleep(100);
00215
if (lock_count != 0)
00216 test_errors++;
00217 pthread_join(test_thread, NULL);
00218
return(test_errors);
00219 }
00220
00221 int ast_base64decode(
unsigned char *dst,
char *src,
int max)
00222 {
00223
int cnt = 0;
00224
unsigned int byte = 0;
00225
unsigned int bits = 0;
00226
int incnt = 0;
00227
#if 0
00228
unsigned char *odst = dst;
00229
#endif
00230
while(*src && (cnt < max)) {
00231
00232 byte <<= 6;
00233 byte |= (b2a[(
int)(*src)]) & 0x3f;
00234 bits += 6;
00235
#if 0
00236
printf(
"Add: %c %s\n", *src, binary(b2a[(
int)(*src)] & 0x3f, 6));
00237
#endif
00238
src++;
00239 incnt++;
00240
00241
00242
if (bits >= 8) {
00243 bits -= 8;
00244 *dst = (byte >> bits) & 0xff;
00245
#if 0
00246
printf(
"Remove: %02x %s\n", *dst, binary(*dst, 8));
00247
#endif
00248
dst++;
00249 cnt++;
00250 }
00251 }
00252
#if 0
00253
dump(odst, cnt);
00254
#endif
00255
00256
return cnt;
00257 }
00258
00259 int ast_base64encode(
char *dst,
unsigned char *src,
int srclen,
int max)
00260 {
00261
int cnt = 0;
00262
unsigned int byte = 0;
00263
int bits = 0;
00264
int index;
00265
int cntin = 0;
00266
#if 0
00267
char *odst = dst;
00268 dump(src, srclen);
00269
#endif
00270
00271 max--;
00272
while((cntin < srclen) && (cnt < max)) {
00273 byte <<= 8;
00274
#if 0
00275
printf(
"Add: %02x %s\n", *src, binary(*src, 8));
00276
#endif
00277
byte |= *(src++);
00278 bits += 8;
00279 cntin++;
00280
while((bits >= 6) && (cnt < max)) {
00281 bits -= 6;
00282
00283 index = (byte >> bits) & 0x3f;
00284 *dst = base64[index];
00285
#if 0
00286
printf(
"Remove: %c %s\n", *dst, binary(index, 6));
00287
#endif
00288
dst++;
00289 cnt++;
00290 }
00291 }
00292
if (bits && (cnt < max)) {
00293
00294
00295 byte <<= (6 - bits);
00296 index = (byte) & 0x3f;
00297 *(dst++) = base64[index];
00298 cnt++;
00299 }
00300 *dst =
'\0';
00301
return cnt;
00302 }
00303
00304
static void base64_init(
void)
00305 {
00306
int x;
00307 memset(b2a, -1,
sizeof(b2a));
00308
00309
for (x=0;x<26;x++) {
00310
00311 base64[x] =
'A' + x;
00312 b2a[
'A' + x] = x;
00313
00314 base64[x + 26] =
'a' + x;
00315 b2a[
'a' + x] = x + 26;
00316
00317
if (x < 10) {
00318 base64[x + 52] =
'0' + x;
00319 b2a[
'0' + x] = x + 52;
00320 }
00321 }
00322 base64[62] =
'+';
00323 base64[63] =
'/';
00324 b2a[(
int)
'+'] = 62;
00325 b2a[(
int)
'/'] = 63;
00326
#if 0
00327
for (x=0;x<64;x++) {
00328
if (b2a[(
int)base64[x]] != x) {
00329 fprintf(stderr,
"!!! %d failed\n", x);
00330 }
else
00331 fprintf(stderr,
"--- %d passed\n", x);
00332 }
00333
#endif
00334
}
00335
00336
00337 const char *
ast_inet_ntoa(
char *buf,
int bufsiz,
struct in_addr ia)
00338 {
00339
return inet_ntop(AF_INET, &ia, buf, bufsiz);
00340 }
00341
00342 int ast_utils_init(
void)
00343 {
00344 base64_init();
00345
return 0;
00346 }