more fixes for gcc4 warnings ...
[asterisk/asterisk.git] / utils.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Utility functions
5  *
6  * Copyright (C)  2004 - 2005, Digium, Inc.
7  *
8  * This program is free software, distributed under the terms of
9  * the GNU General Public License
10  */
11
12 #include <ctype.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include <errno.h>
17 #include <stdarg.h>
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #include <stdarg.h>
24
25 #include "asterisk.h"
26
27 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
28
29 #include "asterisk/lock.h"
30 #include "asterisk/io.h"
31 #include "asterisk/logger.h"
32 #include "asterisk/md5.h"
33 #include "asterisk/options.h"
34
35 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
36 #include "asterisk/strings.h"
37
38 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
39 #include "asterisk/time.h"
40
41 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
42 #include "asterisk/utils.h"
43
44 static char base64[64];
45 static char b2a[256];
46
47 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
48
49 /* duh? ERANGE value copied from web... */
50 #define ERANGE 34
51 #undef gethostbyname
52
53 AST_MUTEX_DEFINE_STATIC(__mutex);
54
55 /* Recursive replacement for gethostbyname for BSD-based systems.  This
56 routine is derived from code originally written and placed in the public 
57 domain by Enzo Michelangeli <em@em.no-ip.com> */
58
59 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
60                                 size_t buflen, struct hostent **result, 
61                                 int *h_errnop) 
62 {
63         int hsave;
64         struct hostent *ph;
65         ast_mutex_lock(&__mutex); /* begin critical area */
66         hsave = h_errno;
67
68         ph = gethostbyname(name);
69         *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
70         if (ph == NULL) {
71                 *result = NULL;
72         } else {
73                 char **p, **q;
74                 char *pbuf;
75                 int nbytes=0;
76                 int naddr=0, naliases=0;
77                 /* determine if we have enough space in buf */
78
79                 /* count how many addresses */
80                 for (p = ph->h_addr_list; *p != 0; p++) {
81                         nbytes += ph->h_length; /* addresses */
82                         nbytes += sizeof(*p); /* pointers */
83                         naddr++;
84                 }
85                 nbytes += sizeof(*p); /* one more for the terminating NULL */
86
87                 /* count how many aliases, and total length of strings */
88                 for (p = ph->h_aliases; *p != 0; p++) {
89                         nbytes += (strlen(*p)+1); /* aliases */
90                         nbytes += sizeof(*p);  /* pointers */
91                         naliases++;
92                 }
93                 nbytes += sizeof(*p); /* one more for the terminating NULL */
94
95                 /* here nbytes is the number of bytes required in buffer */
96                 /* as a terminator must be there, the minimum value is ph->h_length */
97                 if(nbytes > buflen) {
98                         *result = NULL;
99                         ast_mutex_unlock(&__mutex); /* end critical area */
100                         return ERANGE; /* not enough space in buf!! */
101                 }
102
103                 /* There is enough space. Now we need to do a deep copy! */
104                 /* Allocation in buffer:
105                         from [0] to [(naddr-1) * sizeof(*p)]:
106                         pointers to addresses
107                         at [naddr * sizeof(*p)]:
108                         NULL
109                         from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
110                         pointers to aliases
111                         at [(naddr+naliases+1) * sizeof(*p)]:
112                         NULL
113                         then naddr addresses (fixed length), and naliases aliases (asciiz).
114                 */
115
116                 *ret = *ph;   /* copy whole structure (not its address!) */
117
118                 /* copy addresses */
119                 q = (char **)buf; /* pointer to pointers area (type: char **) */
120                 ret->h_addr_list = q; /* update pointer to address list */
121                 pbuf = buf + ((naddr+naliases+2)*sizeof(*p)); /* skip that area */
122                 for (p = ph->h_addr_list; *p != 0; p++) {
123                         memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
124                         *q++ = pbuf; /* the pointer is the one inside buf... */
125                         pbuf += ph->h_length; /* advance pbuf */
126                 }
127                 *q++ = NULL; /* address list terminator */
128
129                 /* copy aliases */
130                 ret->h_aliases = q; /* update pointer to aliases list */
131                 for (p = ph->h_aliases; *p != 0; p++) {
132                         strcpy(pbuf, *p); /* copy alias strings */
133                         *q++ = pbuf; /* the pointer is the one inside buf... */
134                         pbuf += strlen(*p); /* advance pbuf */
135                         *pbuf++ = 0; /* string terminator */
136                 }
137                 *q++ = NULL; /* terminator */
138
139                 strcpy(pbuf, ph->h_name); /* copy alias strings */
140                 ret->h_name = pbuf;
141                 pbuf += strlen(ph->h_name); /* advance pbuf */
142                 *pbuf++ = 0; /* string terminator */
143
144                 *result = ret;  /* and let *result point to structure */
145
146         }
147         h_errno = hsave;  /* restore h_errno */
148         ast_mutex_unlock(&__mutex); /* end critical area */
149
150         return (*result == NULL); /* return 0 on success, non-zero on error */
151 }
152
153
154 #endif
155
156 /* Re-entrant (thread safe) version of gethostbyname that replaces the 
157    standard gethostbyname (which is not thread safe)
158 */
159 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
160 {
161         int res;
162         int herrno;
163         const char *s;
164         struct hostent *result = NULL;
165         /* Although it is perfectly legitimate to lookup a pure integer, for
166            the sake of the sanity of people who like to name their peers as
167            integers, we break with tradition and refuse to look up a
168            pure integer */
169         s = host;
170         res = 0;
171         while(s && *s) {
172                 if (!isdigit(*s))
173                         break;
174                 s++;
175         }
176         if (!s || !*s)
177                 return NULL;
178 #ifdef SOLARIS
179         result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
180
181         if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
182                 return NULL;
183 #else
184         res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
185
186         if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
187                 return NULL;
188 #endif
189         return &hp->hp;
190 }
191
192
193 /* This is a regression test for recursive mutexes.
194    test_for_thread_safety() will return 0 if recursive mutex locks are
195    working properly, and non-zero if they are not working properly. */
196
197 AST_MUTEX_DEFINE_STATIC(test_lock);
198 AST_MUTEX_DEFINE_STATIC(test_lock2);
199 static pthread_t test_thread; 
200 static int lock_count = 0;
201 static int test_errors = 0;
202
203 static void *test_thread_body(void *data) 
204
205         ast_mutex_lock(&test_lock);
206         lock_count += 10;
207         if (lock_count != 10) 
208                 test_errors++;
209         ast_mutex_lock(&test_lock);
210         lock_count += 10;
211         if (lock_count != 20) 
212                 test_errors++;
213         ast_mutex_lock(&test_lock2);
214         ast_mutex_unlock(&test_lock);
215         lock_count -= 10;
216         if (lock_count != 10) 
217                 test_errors++;
218         ast_mutex_unlock(&test_lock);
219         lock_count -= 10;
220         ast_mutex_unlock(&test_lock2);
221         if (lock_count != 0) 
222                 test_errors++;
223         return NULL;
224
225
226 int test_for_thread_safety(void)
227
228         ast_mutex_lock(&test_lock2);
229         ast_mutex_lock(&test_lock);
230         lock_count += 1;
231         ast_mutex_lock(&test_lock);
232         lock_count += 1;
233         ast_pthread_create(&test_thread, NULL, test_thread_body, NULL); 
234         usleep(100);
235         if (lock_count != 2) 
236                 test_errors++;
237         ast_mutex_unlock(&test_lock);
238         lock_count -= 1;
239         usleep(100); 
240         if (lock_count != 1) 
241                 test_errors++;
242         ast_mutex_unlock(&test_lock);
243         lock_count -= 1;
244         if (lock_count != 0) 
245                 test_errors++;
246         ast_mutex_unlock(&test_lock2);
247         usleep(100);
248         if (lock_count != 0) 
249                 test_errors++;
250         pthread_join(test_thread, NULL);
251         return(test_errors);          /* return 0 on success. */
252 }
253
254 /*--- ast_md5_hash: Produce 16 char MD5 hash of value. ---*/
255 void ast_md5_hash(char *output, char *input)
256 {
257         struct MD5Context md5;
258         unsigned char digest[16];
259         char *ptr;
260         int x;
261
262         MD5Init(&md5);
263         MD5Update(&md5, (unsigned char *)input, strlen(input));
264         MD5Final(digest, &md5);
265         ptr = output;
266         for (x=0; x<16; x++)
267                 ptr += sprintf(ptr, "%2.2x", digest[x]);
268 }
269
270 int ast_base64decode(unsigned char *dst, char *src, int max)
271 {
272         int cnt = 0;
273         unsigned int byte = 0;
274         unsigned int bits = 0;
275         int incnt = 0;
276 #if 0
277         unsigned char *odst = dst;
278 #endif
279         while(*src && (cnt < max)) {
280                 /* Shift in 6 bits of input */
281                 byte <<= 6;
282                 byte |= (b2a[(int)(*src)]) & 0x3f;
283                 bits += 6;
284 #if 0
285                 printf("Add: %c %s\n", *src, binary(b2a[(int)(*src)] & 0x3f, 6));
286 #endif
287                 src++;
288                 incnt++;
289                 /* If we have at least 8 bits left over, take that character 
290                    off the top */
291                 if (bits >= 8)  {
292                         bits -= 8;
293                         *dst = (byte >> bits) & 0xff;
294 #if 0
295                         printf("Remove: %02x %s\n", *dst, binary(*dst, 8));
296 #endif
297                         dst++;
298                         cnt++;
299                 }
300         }
301 #if 0
302         dump(odst, cnt);
303 #endif
304         /* Dont worry about left over bits, they're extra anyway */
305         return cnt;
306 }
307
308 int ast_base64encode(char *dst, unsigned char *src, int srclen, int max)
309 {
310         int cnt = 0;
311         unsigned int byte = 0;
312         int bits = 0;
313         int index;
314         int cntin = 0;
315 #if 0
316         char *odst = dst;
317         dump(src, srclen);
318 #endif
319         /* Reserve one bit for end */
320         max--;
321         while((cntin < srclen) && (cnt < max)) {
322                 byte <<= 8;
323 #if 0
324                 printf("Add: %02x %s\n", *src, binary(*src, 8));
325 #endif
326                 byte |= *(src++);
327                 bits += 8;
328                 cntin++;
329                 while((bits >= 6) && (cnt < max)) {
330                         bits -= 6;
331                         /* We want only the top */
332                         index = (byte >> bits) & 0x3f;
333                         *dst = base64[index];
334 #if 0
335                         printf("Remove: %c %s\n", *dst, binary(index, 6));
336 #endif
337                         dst++;
338                         cnt++;
339                 }
340         }
341         if (bits && (cnt < max)) {
342                 /* Add one last character for the remaining bits, 
343                    padding the rest with 0 */
344                 byte <<= (6 - bits);
345                 index = (byte) & 0x3f;
346                 *(dst++) = base64[index];
347                 cnt++;
348         }
349         *dst = '\0';
350         return cnt;
351 }
352
353 static void base64_init(void)
354 {
355         int x;
356         memset(b2a, -1, sizeof(b2a));
357         /* Initialize base-64 Conversion table */
358         for (x=0;x<26;x++) {
359                 /* A-Z */
360                 base64[x] = 'A' + x;
361                 b2a['A' + x] = x;
362                 /* a-z */
363                 base64[x + 26] = 'a' + x;
364                 b2a['a' + x] = x + 26;
365                 /* 0-9 */
366                 if (x < 10) {
367                         base64[x + 52] = '0' + x;
368                         b2a['0' + x] = x + 52;
369                 }
370         }
371         base64[62] = '+';
372         base64[63] = '/';
373         b2a[(int)'+'] = 62;
374         b2a[(int)'/'] = 63;
375 #if 0
376         for (x=0;x<64;x++) {
377                 if (b2a[(int)base64[x]] != x) {
378                         fprintf(stderr, "!!! %d failed\n", x);
379                 } else
380                         fprintf(stderr, "--- %d passed\n", x);
381         }
382 #endif
383 }
384
385 /* Recursive thread safe replacement of inet_ntoa */
386 const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia)
387 {
388         return inet_ntop(AF_INET, &ia, buf, bufsiz);
389 }
390
391 int ast_utils_init(void)
392 {
393         base64_init();
394         return 0;
395 }
396
397 #ifndef __linux__
398 #undef pthread_create /* For ast_pthread_create function only */
399 #endif /* ! LINUX */
400 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize)
401 {
402         pthread_attr_t lattr;
403         if (!attr) {
404                 pthread_attr_init(&lattr);
405                 attr = &lattr;
406         }
407         if (!stacksize)
408                 stacksize = AST_STACKSIZE;
409         errno = pthread_attr_setstacksize(attr, stacksize);
410         if (errno)
411                 ast_log(LOG_WARNING, "pthread_attr_setstacksize returned non-zero: %s\n", strerror(errno));
412         return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
413 }
414
415 int ast_wait_for_input(int fd, int ms)
416 {
417         struct pollfd pfd[1];
418         memset(pfd, 0, sizeof(pfd));
419         pfd[0].fd = fd;
420         pfd[0].events = POLLIN|POLLPRI;
421         return poll(pfd, 1, ms);
422 }
423
424 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
425 {
426         char *e;
427         char *q;
428
429         s = ast_strip(s);
430         if ((q = strchr(beg_quotes, *s))) {
431                 e = s + strlen(s) - 1;
432                 if (*e == *(end_quotes + (q - beg_quotes))) {
433                         s++;
434                         *e = '\0';
435                 }
436         }
437
438         return s;
439 }
440
441 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
442 {
443         va_list ap;
444         int result;
445
446         if (!buffer || !*buffer || !space || !*space)
447                 return -1;
448
449         va_start(ap, fmt);
450         result = vsnprintf(*buffer, *space, fmt, ap);
451         va_end(ap);
452
453         if (result < 0)
454                 return -1;
455         else if (result > *space)
456                 result = *space;
457
458         *buffer += result;
459         *space -= result;
460         return 0;
461 }
462
463 int ast_true(const char *s)
464 {
465         if (!s || ast_strlen_zero(s))
466                 return 0;
467
468         /* Determine if this is a true value */
469         if (!strcasecmp(s, "yes") ||
470             !strcasecmp(s, "true") ||
471             !strcasecmp(s, "y") ||
472             !strcasecmp(s, "t") ||
473             !strcasecmp(s, "1") ||
474             !strcasecmp(s, "on"))
475                 return -1;
476
477         return 0;
478 }
479
480 int ast_false(const char *s)
481 {
482         if (!s || ast_strlen_zero(s))
483                 return 0;
484
485         /* Determine if this is a false value */
486         if (!strcasecmp(s, "no") ||
487             !strcasecmp(s, "false") ||
488             !strcasecmp(s, "n") ||
489             !strcasecmp(s, "f") ||
490             !strcasecmp(s, "0") ||
491             !strcasecmp(s, "off"))
492                 return -1;
493
494         return 0;
495 }
496
497 #define ONE_MILLION     1000000
498 /*
499  * put timeval in a valid range. usec is 0..999999
500  * negative values are not allowed and truncated.
501  */
502 static struct timeval tvfix(struct timeval a)
503 {
504         if (a.tv_usec >= ONE_MILLION) {
505                 ast_log(LOG_ERROR, "warning too large timestamp %ld.%ld\n",
506                         a.tv_sec, a.tv_usec);
507                 a.tv_sec += a.tv_usec % ONE_MILLION;
508                 a.tv_usec %= ONE_MILLION;
509         } else if (a.tv_usec < 0) {
510                 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
511                                 a.tv_sec, a.tv_usec);
512                 a.tv_usec = 0;
513         }
514         return a;
515 }
516
517 struct timeval ast_tvadd(struct timeval a, struct timeval b)
518 {
519         /* consistency checks to guarantee usec in 0..999999 */
520         a = tvfix(a);
521         b = tvfix(b);
522         a.tv_sec += b.tv_sec;
523         a.tv_usec += b.tv_usec;
524         if (a.tv_usec >= ONE_MILLION) {
525                 a.tv_sec++;
526                 a.tv_usec -= ONE_MILLION;
527         }
528         return a;
529 }
530
531 struct timeval ast_tvsub(struct timeval a, struct timeval b)
532 {
533         /* consistency checks to guarantee usec in 0..999999 */
534         a = tvfix(a);
535         b = tvfix(b);
536         a.tv_sec -= b.tv_sec;
537         a.tv_usec -= b.tv_usec;
538         if (a.tv_usec < 0) {
539                 a.tv_sec-- ;
540                 a.tv_usec += ONE_MILLION;
541         }
542         return a;
543 }
544 #undef ONE_MILLION
545
546 #ifndef HAVE_STRCASESTR
547 static char *upper(const char *orig, char *buf, int bufsize)
548 {
549         int i = 0;
550
551         while (i < (bufsize - 1) && orig[i]) {
552                 buf[i] = toupper(orig[i]);
553                 i++;
554         }
555
556         buf[i] = '\0';
557
558         return buf;
559 }
560
561 char *strcasestr(const char *haystack, const char *needle)
562 {
563         char *u1, *u2;
564         int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
565
566         u1 = alloca(u1len);
567         u2 = alloca(u2len);
568         if (u1 && u2) {
569                 char *offset;
570                 if (u2len > u1len) {
571                         /* Needle bigger than haystack */
572                         return NULL;
573                 }
574                 offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
575                 if (offset) {
576                         /* Return the offset into the original string */
577                         return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
578                 } else {
579                         return NULL;
580                 }
581         } else {
582                 ast_log(LOG_ERROR, "Out of memory\n");
583                 return NULL;
584         }
585 }
586 #endif
587
588 #ifndef HAVE_STRNLEN
589 size_t strnlen(const char *s, size_t n)
590 {
591         size_t len;
592
593         for (len=0; len < n; len++)
594                 if (s[len] == '\0')
595                         break;
596
597         return len;
598 }
599 #endif
600
601 #ifndef HAVE_STRNDUP
602 char *strndup(const char *s, size_t n)
603 {
604         size_t len = strnlen(s, n);
605         char *new = malloc(len + 1);
606
607         if (!new)
608                 return NULL;
609
610         new[len] = '\0';
611         return memcpy(new, s, len);
612 }
613 #endif
614
615 #ifndef HAVE_VASPRINTF
616 int vasprintf(char **strp, const char *fmt, va_list ap)
617 {
618         int size;
619         va_list ap2;
620         char s;
621
622         *strp = NULL;
623         va_copy(ap2, ap);
624         size = vsnprintf(&s, 1, fmt, ap2);
625         va_end(ap2);
626         *strp = malloc(size + 1);
627         if (!*strp)
628                 return -1;
629         vsnprintf(*strp, size + 1, fmt, ap);
630
631         return size;
632 }
633 #endif
634
635 #ifndef HAVE_STRTOQ
636 #define LONG_MIN        (-9223372036854775807L-1L)
637                                         /* min value of a "long int" */
638 #define LONG_MAX        9223372036854775807L
639                                         /* max value of a "long int" */
640
641 /*
642  * Convert a string to a quad integer.
643  *
644  * Ignores `locale' stuff.  Assumes that the upper and lower case
645  * alphabets and digits are each contiguous.
646  */
647 uint64_t strtoq(const char *nptr, char **endptr, int base)
648 {
649         const char *s;
650         uint64_t acc;
651         unsigned char c;
652         uint64_t qbase, cutoff;
653         int neg, any, cutlim;
654
655         /*
656          * Skip white space and pick up leading +/- sign if any.
657          * If base is 0, allow 0x for hex and 0 for octal, else
658          * assume decimal; if base is already 16, allow 0x.
659          */
660         s = nptr;
661         do {
662                 c = *s++;
663         } while (isspace(c));
664         if (c == '-') {
665                 neg = 1;
666                 c = *s++;
667         } else {
668                 neg = 0;
669                 if (c == '+')
670                         c = *s++;
671         }
672         if ((base == 0 || base == 16) &&
673             c == '\0' && (*s == 'x' || *s == 'X')) {
674                 c = s[1];
675                 s += 2;
676                 base = 16;
677         }
678         if (base == 0)
679                 base = c == '\0' ? 8 : 10;
680
681         /*
682          * Compute the cutoff value between legal numbers and illegal
683          * numbers.  That is the largest legal value, divided by the
684          * base.  An input number that is greater than this value, if
685          * followed by a legal input character, is too big.  One that
686          * is equal to this value may be valid or not; the limit
687          * between valid and invalid numbers is then based on the last
688          * digit.  For instance, if the range for quads is
689          * [-9223372036854775808..9223372036854775807] and the input base
690          * is 10, cutoff will be set to 922337203685477580 and cutlim to
691          * either 7 (neg==0) or 8 (neg==1), meaning that if we have
692          * accumulated a value > 922337203685477580, or equal but the
693          * next digit is > 7 (or 8), the number is too big, and we will
694          * return a range error.
695          *
696          * Set any if any `digits' consumed; make it negative to indicate
697          * overflow.
698          */
699         qbase = (unsigned)base;
700         cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
701         cutlim = cutoff % qbase;
702         cutoff /= qbase;
703         for (acc = 0, any = 0;; c = *s++) {
704                 if (!isascii(c))
705                         break;
706                 if (isdigit(c))
707                         c -= '\0';
708                 else if (isalpha(c))
709                         c -= isupper(c) ? 'A' - 10 : 'a' - 10;
710                 else
711                         break;
712                 if (c >= base)
713                         break;
714                 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
715                         any = -1;
716                 else {
717                         any = 1;
718                         acc *= qbase;
719                         acc += c;
720                 }
721         }
722         if (any < 0) {
723                 acc = neg ? LONG_MIN : LONG_MAX;
724         } else if (neg)
725                 acc = -acc;
726         if (endptr != 0)
727                 *((const char **)endptr) = any ? s - 1 : nptr;
728         return (acc);
729 }
730 #endif