issue #5638
[asterisk/asterisk.git] / utils.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief Utility functions
20  *
21  * \note These are important for portability and security,
22  * so please use them in favour of other routines.
23  * Please consult the CODING GUIDELINES for more information.
24  */
25
26 #include <ctype.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37
38 #include "asterisk.h"
39
40 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
41
42 #include "asterisk/lock.h"
43 #include "asterisk/io.h"
44 #include "asterisk/logger.h"
45 #include "asterisk/md5.h"
46 #include "asterisk/options.h"
47 #include "asterisk/compat.h"
48
49 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
50 #include "asterisk/strings.h"
51
52 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
53 #include "asterisk/time.h"
54
55 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
56 #include "asterisk/utils.h"
57
58 static char base64[64];
59 static char b2a[256];
60
61 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) || defined(__CYGWIN__)
62
63 /* duh? ERANGE value copied from web... */
64 #define ERANGE 34
65 #undef gethostbyname
66
67 AST_MUTEX_DEFINE_STATIC(__mutex);
68
69 /* Recursive replacement for gethostbyname for BSD-based systems.  This
70 routine is derived from code originally written and placed in the public 
71 domain by Enzo Michelangeli <em@em.no-ip.com> */
72
73 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
74                                 size_t buflen, struct hostent **result, 
75                                 int *h_errnop) 
76 {
77         int hsave;
78         struct hostent *ph;
79         ast_mutex_lock(&__mutex); /* begin critical area */
80         hsave = h_errno;
81
82         ph = gethostbyname(name);
83         *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
84         if (ph == NULL) {
85                 *result = NULL;
86         } else {
87                 char **p, **q;
88                 char *pbuf;
89                 int nbytes=0;
90                 int naddr=0, naliases=0;
91                 /* determine if we have enough space in buf */
92
93                 /* count how many addresses */
94                 for (p = ph->h_addr_list; *p != 0; p++) {
95                         nbytes += ph->h_length; /* addresses */
96                         nbytes += sizeof(*p); /* pointers */
97                         naddr++;
98                 }
99                 nbytes += sizeof(*p); /* one more for the terminating NULL */
100
101                 /* count how many aliases, and total length of strings */
102                 for (p = ph->h_aliases; *p != 0; p++) {
103                         nbytes += (strlen(*p)+1); /* aliases */
104                         nbytes += sizeof(*p);  /* pointers */
105                         naliases++;
106                 }
107                 nbytes += sizeof(*p); /* one more for the terminating NULL */
108
109                 /* here nbytes is the number of bytes required in buffer */
110                 /* as a terminator must be there, the minimum value is ph->h_length */
111                 if(nbytes > buflen) {
112                         *result = NULL;
113                         ast_mutex_unlock(&__mutex); /* end critical area */
114                         return ERANGE; /* not enough space in buf!! */
115                 }
116
117                 /* There is enough space. Now we need to do a deep copy! */
118                 /* Allocation in buffer:
119                         from [0] to [(naddr-1) * sizeof(*p)]:
120                         pointers to addresses
121                         at [naddr * sizeof(*p)]:
122                         NULL
123                         from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
124                         pointers to aliases
125                         at [(naddr+naliases+1) * sizeof(*p)]:
126                         NULL
127                         then naddr addresses (fixed length), and naliases aliases (asciiz).
128                 */
129
130                 *ret = *ph;   /* copy whole structure (not its address!) */
131
132                 /* copy addresses */
133                 q = (char **)buf; /* pointer to pointers area (type: char **) */
134                 ret->h_addr_list = q; /* update pointer to address list */
135                 pbuf = buf + ((naddr+naliases+2)*sizeof(*p)); /* skip that area */
136                 for (p = ph->h_addr_list; *p != 0; p++) {
137                         memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
138                         *q++ = pbuf; /* the pointer is the one inside buf... */
139                         pbuf += ph->h_length; /* advance pbuf */
140                 }
141                 *q++ = NULL; /* address list terminator */
142
143                 /* copy aliases */
144                 ret->h_aliases = q; /* update pointer to aliases list */
145                 for (p = ph->h_aliases; *p != 0; p++) {
146                         strcpy(pbuf, *p); /* copy alias strings */
147                         *q++ = pbuf; /* the pointer is the one inside buf... */
148                         pbuf += strlen(*p); /* advance pbuf */
149                         *pbuf++ = 0; /* string terminator */
150                 }
151                 *q++ = NULL; /* terminator */
152
153                 strcpy(pbuf, ph->h_name); /* copy alias strings */
154                 ret->h_name = pbuf;
155                 pbuf += strlen(ph->h_name); /* advance pbuf */
156                 *pbuf++ = 0; /* string terminator */
157
158                 *result = ret;  /* and let *result point to structure */
159
160         }
161         h_errno = hsave;  /* restore h_errno */
162         ast_mutex_unlock(&__mutex); /* end critical area */
163
164         return (*result == NULL); /* return 0 on success, non-zero on error */
165 }
166
167
168 #endif
169
170 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the 
171    standard gethostbyname (which is not thread safe)
172 */
173 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
174 {
175         int res;
176         int herrno;
177         int dots=0;
178         const char *s;
179         struct hostent *result = NULL;
180         /* Although it is perfectly legitimate to lookup a pure integer, for
181            the sake of the sanity of people who like to name their peers as
182            integers, we break with tradition and refuse to look up a
183            pure integer */
184         s = host;
185         res = 0;
186         while(s && *s) {
187                 if (*s == '.')
188                         dots++;
189                 else if (!isdigit(*s))
190                         break;
191                 s++;
192         }
193         if (!s || !*s) {
194                 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
195                 if (dots != 3)
196                         return NULL;
197                 memset(hp, 0, sizeof(struct ast_hostent));
198                 hp->hp.h_addr_list = (void *) hp->buf;
199                 hp->hp.h_addr = hp->buf + sizeof(void *);
200                 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
201                         return &hp->hp;
202                 return NULL;
203                 
204         }
205 #ifdef SOLARIS
206         result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
207
208         if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
209                 return NULL;
210 #else
211         res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
212
213         if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
214                 return NULL;
215 #endif
216         return &hp->hp;
217 }
218
219
220
221 AST_MUTEX_DEFINE_STATIC(test_lock);
222 AST_MUTEX_DEFINE_STATIC(test_lock2);
223 static pthread_t test_thread; 
224 static int lock_count = 0;
225 static int test_errors = 0;
226
227 /*! \brief This is a regression test for recursive mutexes.
228    test_for_thread_safety() will return 0 if recursive mutex locks are
229    working properly, and non-zero if they are not working properly. */
230 static void *test_thread_body(void *data) 
231
232         ast_mutex_lock(&test_lock);
233         lock_count += 10;
234         if (lock_count != 10) 
235                 test_errors++;
236         ast_mutex_lock(&test_lock);
237         lock_count += 10;
238         if (lock_count != 20) 
239                 test_errors++;
240         ast_mutex_lock(&test_lock2);
241         ast_mutex_unlock(&test_lock);
242         lock_count -= 10;
243         if (lock_count != 10) 
244                 test_errors++;
245         ast_mutex_unlock(&test_lock);
246         lock_count -= 10;
247         ast_mutex_unlock(&test_lock2);
248         if (lock_count != 0) 
249                 test_errors++;
250         return NULL;
251
252
253 int test_for_thread_safety(void)
254
255         ast_mutex_lock(&test_lock2);
256         ast_mutex_lock(&test_lock);
257         lock_count += 1;
258         ast_mutex_lock(&test_lock);
259         lock_count += 1;
260         ast_pthread_create(&test_thread, NULL, test_thread_body, NULL); 
261         usleep(100);
262         if (lock_count != 2) 
263                 test_errors++;
264         ast_mutex_unlock(&test_lock);
265         lock_count -= 1;
266         usleep(100); 
267         if (lock_count != 1) 
268                 test_errors++;
269         ast_mutex_unlock(&test_lock);
270         lock_count -= 1;
271         if (lock_count != 0) 
272                 test_errors++;
273         ast_mutex_unlock(&test_lock2);
274         usleep(100);
275         if (lock_count != 0) 
276                 test_errors++;
277         pthread_join(test_thread, NULL);
278         return(test_errors);          /* return 0 on success. */
279 }
280
281 /*! \brief ast_md5_hash: Produce 16 char MD5 hash of value. ---*/
282 void ast_md5_hash(char *output, char *input)
283 {
284         struct MD5Context md5;
285         unsigned char digest[16];
286         char *ptr;
287         int x;
288
289         MD5Init(&md5);
290         MD5Update(&md5, (unsigned char *)input, strlen(input));
291         MD5Final(digest, &md5);
292         ptr = output;
293         for (x=0; x<16; x++)
294                 ptr += sprintf(ptr, "%2.2x", digest[x]);
295 }
296
297 int ast_base64decode(unsigned char *dst, const char *src, int max)
298 {
299         int cnt = 0;
300         unsigned int byte = 0;
301         unsigned int bits = 0;
302         int incnt = 0;
303 #if 0
304         unsigned char *odst = dst;
305 #endif
306         while(*src && (cnt < max)) {
307                 /* Shift in 6 bits of input */
308                 byte <<= 6;
309                 byte |= (b2a[(int)(*src)]) & 0x3f;
310                 bits += 6;
311 #if 0
312                 printf("Add: %c %s\n", *src, binary(b2a[(int)(*src)] & 0x3f, 6));
313 #endif
314                 src++;
315                 incnt++;
316                 /* If we have at least 8 bits left over, take that character 
317                    off the top */
318                 if (bits >= 8)  {
319                         bits -= 8;
320                         *dst = (byte >> bits) & 0xff;
321 #if 0
322                         printf("Remove: %02x %s\n", *dst, binary(*dst, 8));
323 #endif
324                         dst++;
325                         cnt++;
326                 }
327         }
328 #if 0
329         dump(odst, cnt);
330 #endif
331         /* Dont worry about left over bits, they're extra anyway */
332         return cnt;
333 }
334
335 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
336 {
337         int cnt = 0;
338         unsigned int byte = 0;
339         int bits = 0;
340         int index;
341         int cntin = 0;
342 #if 0
343         char *odst = dst;
344         dump(src, srclen);
345 #endif
346         /* Reserve one bit for end */
347         max--;
348         while((cntin < srclen) && (cnt < max)) {
349                 byte <<= 8;
350 #if 0
351                 printf("Add: %02x %s\n", *src, binary(*src, 8));
352 #endif
353                 byte |= *(src++);
354                 bits += 8;
355                 cntin++;
356                 while((bits >= 6) && (cnt < max)) {
357                         bits -= 6;
358                         /* We want only the top */
359                         index = (byte >> bits) & 0x3f;
360                         *dst = base64[index];
361 #if 0
362                         printf("Remove: %c %s\n", *dst, binary(index, 6));
363 #endif
364                         dst++;
365                         cnt++;
366                 }
367         }
368         if (bits && (cnt < max)) {
369                 /* Add one last character for the remaining bits, 
370                    padding the rest with 0 */
371                 byte <<= (6 - bits);
372                 index = (byte) & 0x3f;
373                 *(dst++) = base64[index];
374                 cnt++;
375         }
376         *dst = '\0';
377         return cnt;
378 }
379
380 static void base64_init(void)
381 {
382         int x;
383         memset(b2a, -1, sizeof(b2a));
384         /* Initialize base-64 Conversion table */
385         for (x=0;x<26;x++) {
386                 /* A-Z */
387                 base64[x] = 'A' + x;
388                 b2a['A' + x] = x;
389                 /* a-z */
390                 base64[x + 26] = 'a' + x;
391                 b2a['a' + x] = x + 26;
392                 /* 0-9 */
393                 if (x < 10) {
394                         base64[x + 52] = '0' + x;
395                         b2a['0' + x] = x + 52;
396                 }
397         }
398         base64[62] = '+';
399         base64[63] = '/';
400         b2a[(int)'+'] = 62;
401         b2a[(int)'/'] = 63;
402 #if 0
403         for (x=0;x<64;x++) {
404                 if (b2a[(int)base64[x]] != x) {
405                         fprintf(stderr, "!!! %d failed\n", x);
406                 } else
407                         fprintf(stderr, "--- %d passed\n", x);
408         }
409 #endif
410 }
411
412 /*! \brief  ast_uri_encode: Turn text string to URI-encoded %XX version ---*/
413 /*      At this point, we're converting from ISO-8859-x (8-bit), not UTF8
414         as in the SIP protocol spec 
415         If doreserved == 1 we will convert reserved characters also.
416         RFC 2396, section 2.4
417         outbuf needs to have more memory allocated than the instring
418         to have room for the expansion. Every char that is converted
419         is replaced by three ASCII characters.
420
421         Note: The doreserved option is needed for replaces header in
422         SIP transfers.
423 */
424 char *ast_uri_encode(char *string, char *outbuf, int buflen, int doreserved) 
425 {
426         char *reserved = ";/?:@&=+$, "; /* Reserved chars */
427
428         char *ptr  = string;    /* Start with the string */
429         char *out = NULL;
430         char *buf = NULL;
431
432         strncpy(outbuf, string, buflen);
433
434         /* If there's no characters to convert, just go through and don't do anything */
435         while (*ptr) {
436                 if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
437                         /* Oops, we need to start working here */
438                         if (!buf) {
439                                 buf = outbuf;
440                                 out = buf + (ptr - string) ;    /* Set output ptr */
441                         }
442                         out += sprintf(out, "%%%02x", (unsigned char) *ptr);
443                 } else if (buf) {
444                         *out = *ptr;    /* Continue copying the string */
445                         out++;
446                 } 
447                 ptr++;
448         }
449         if (buf)
450                 *out = '\0';
451         return outbuf;
452 }
453
454 /*! \brief  ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)  ---*/
455 void ast_uri_decode(char *s) 
456 {
457         char *o;
458         unsigned int tmp;
459
460         for (o = s; *s; s++, o++) {
461                 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
462                         /* have '%', two chars and correct parsing */
463                         *o = tmp;
464                         s += 2; /* Will be incremented once more when we break out */
465                 } else /* all other cases, just copy */
466                         *o = *s;
467         }
468         *o = '\0';
469 }
470
471 /*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
472 const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia)
473 {
474         return inet_ntop(AF_INET, &ia, buf, bufsiz);
475 }
476
477 int ast_utils_init(void)
478 {
479         base64_init();
480         return 0;
481 }
482
483 #ifndef __linux__
484 #undef pthread_create /* For ast_pthread_create function only */
485 #endif /* !__linux__ */
486
487 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize)
488 {
489         pthread_attr_t lattr;
490         if (!attr) {
491                 pthread_attr_init(&lattr);
492                 attr = &lattr;
493         }
494 #ifdef __linux__
495         /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
496            which is kind of useless. Change this here to
497            PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
498            priority will propagate down to new threads by default.
499            This does mean that callers cannot set a different priority using
500            PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
501            the priority afterwards with pthread_setschedparam(). */
502         errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED);
503         if (errno)
504                 ast_log(LOG_WARNING, "pthread_attr_setinheritsched returned non-zero: %s\n", strerror(errno));
505 #endif
506
507         if (!stacksize)
508                 stacksize = AST_STACKSIZE;
509         errno = pthread_attr_setstacksize(attr, stacksize);
510         if (errno)
511                 ast_log(LOG_WARNING, "pthread_attr_setstacksize returned non-zero: %s\n", strerror(errno));
512         return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
513 }
514
515 int ast_wait_for_input(int fd, int ms)
516 {
517         struct pollfd pfd[1];
518         memset(pfd, 0, sizeof(pfd));
519         pfd[0].fd = fd;
520         pfd[0].events = POLLIN|POLLPRI;
521         return poll(pfd, 1, ms);
522 }
523
524 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
525 {
526         char *e;
527         char *q;
528
529         s = ast_strip(s);
530         if ((q = strchr(beg_quotes, *s))) {
531                 e = s + strlen(s) - 1;
532                 if (*e == *(end_quotes + (q - beg_quotes))) {
533                         s++;
534                         *e = '\0';
535                 }
536         }
537
538         return s;
539 }
540
541 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
542 {
543         int result;
544
545         if (!buffer || !*buffer || !space || !*space)
546                 return -1;
547
548         result = vsnprintf(*buffer, *space, fmt, ap);
549
550         if (result < 0)
551                 return -1;
552         else if (result > *space)
553                 result = *space;
554
555         *buffer += result;
556         *space -= result;
557         return 0;
558 }
559
560 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
561 {
562         va_list ap;
563         int result;
564
565         va_start(ap, fmt);
566         result = ast_build_string_va(buffer, space, fmt, ap);
567         va_end(ap);
568
569         return result;
570 }
571
572 int ast_true(const char *s)
573 {
574         if (ast_strlen_zero(s))
575                 return 0;
576
577         /* Determine if this is a true value */
578         if (!strcasecmp(s, "yes") ||
579             !strcasecmp(s, "true") ||
580             !strcasecmp(s, "y") ||
581             !strcasecmp(s, "t") ||
582             !strcasecmp(s, "1") ||
583             !strcasecmp(s, "on"))
584                 return -1;
585
586         return 0;
587 }
588
589 int ast_false(const char *s)
590 {
591         if (ast_strlen_zero(s))
592                 return 0;
593
594         /* Determine if this is a false value */
595         if (!strcasecmp(s, "no") ||
596             !strcasecmp(s, "false") ||
597             !strcasecmp(s, "n") ||
598             !strcasecmp(s, "f") ||
599             !strcasecmp(s, "0") ||
600             !strcasecmp(s, "off"))
601                 return -1;
602
603         return 0;
604 }
605
606 #define ONE_MILLION     1000000
607 /*
608  * put timeval in a valid range. usec is 0..999999
609  * negative values are not allowed and truncated.
610  */
611 static struct timeval tvfix(struct timeval a)
612 {
613         if (a.tv_usec >= ONE_MILLION) {
614                 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
615                         a.tv_sec, (long int) a.tv_usec);
616                 a.tv_sec += a.tv_usec % ONE_MILLION;
617                 a.tv_usec %= ONE_MILLION;
618         } else if (a.tv_usec < 0) {
619                 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
620                                 a.tv_sec, (long int) a.tv_usec);
621                 a.tv_usec = 0;
622         }
623         return a;
624 }
625
626 struct timeval ast_tvadd(struct timeval a, struct timeval b)
627 {
628         /* consistency checks to guarantee usec in 0..999999 */
629         a = tvfix(a);
630         b = tvfix(b);
631         a.tv_sec += b.tv_sec;
632         a.tv_usec += b.tv_usec;
633         if (a.tv_usec >= ONE_MILLION) {
634                 a.tv_sec++;
635                 a.tv_usec -= ONE_MILLION;
636         }
637         return a;
638 }
639
640 struct timeval ast_tvsub(struct timeval a, struct timeval b)
641 {
642         /* consistency checks to guarantee usec in 0..999999 */
643         a = tvfix(a);
644         b = tvfix(b);
645         a.tv_sec -= b.tv_sec;
646         a.tv_usec -= b.tv_usec;
647         if (a.tv_usec < 0) {
648                 a.tv_sec-- ;
649                 a.tv_usec += ONE_MILLION;
650         }
651         return a;
652 }
653 #undef ONE_MILLION
654
655 #ifndef HAVE_STRCASESTR
656 static char *upper(const char *orig, char *buf, int bufsize)
657 {
658         int i = 0;
659
660         while (i < (bufsize - 1) && orig[i]) {
661                 buf[i] = toupper(orig[i]);
662                 i++;
663         }
664
665         buf[i] = '\0';
666
667         return buf;
668 }
669
670 char *strcasestr(const char *haystack, const char *needle)
671 {
672         char *u1, *u2;
673         int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
674
675         u1 = alloca(u1len);
676         u2 = alloca(u2len);
677         if (u1 && u2) {
678                 char *offset;
679                 if (u2len > u1len) {
680                         /* Needle bigger than haystack */
681                         return NULL;
682                 }
683                 offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
684                 if (offset) {
685                         /* Return the offset into the original string */
686                         return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
687                 } else {
688                         return NULL;
689                 }
690         } else {
691                 ast_log(LOG_ERROR, "Out of memory\n");
692                 return NULL;
693         }
694 }
695 #endif /* !HAVE_STRCASESTR */
696
697 #ifndef HAVE_STRNLEN
698 size_t strnlen(const char *s, size_t n)
699 {
700         size_t len;
701
702         for (len=0; len < n; len++)
703                 if (s[len] == '\0')
704                         break;
705
706         return len;
707 }
708 #endif /* !HAVE_STRNLEN */
709
710 #if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
711 char *strndup(const char *s, size_t n)
712 {
713         size_t len = strnlen(s, n);
714         char *new = malloc(len + 1);
715
716         if (!new)
717                 return NULL;
718
719         new[len] = '\0';
720         return memcpy(new, s, len);
721 }
722 #endif /* !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC) */
723
724 #if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
725 int vasprintf(char **strp, const char *fmt, va_list ap)
726 {
727         int size;
728         va_list ap2;
729         char s;
730
731         *strp = NULL;
732         va_copy(ap2, ap);
733         size = vsnprintf(&s, 1, fmt, ap2);
734         va_end(ap2);
735         *strp = malloc(size + 1);
736         if (!*strp)
737                 return -1;
738         vsnprintf(*strp, size + 1, fmt, ap);
739
740         return size;
741 }
742 #endif /* !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
743
744 #ifndef HAVE_STRTOQ
745 #ifndef LONG_MIN
746 #define LONG_MIN        (-9223372036854775807L-1L)
747                                          /* min value of a "long int" */
748 #endif
749 #ifndef LONG_MAX
750 #define LONG_MAX        9223372036854775807L
751                                          /* max value of a "long int" */
752 #endif
753
754 /*
755  * Convert a string to a quad integer.
756  *
757  * Ignores `locale' stuff.  Assumes that the upper and lower case
758  * alphabets and digits are each contiguous.
759  */
760 uint64_t strtoq(const char *nptr, char **endptr, int base)
761 {
762          const char *s;
763          uint64_t acc;
764          unsigned char c;
765          uint64_t qbase, cutoff;
766          int neg, any, cutlim;
767
768          /*
769           * Skip white space and pick up leading +/- sign if any.
770           * If base is 0, allow 0x for hex and 0 for octal, else
771           * assume decimal; if base is already 16, allow 0x.
772           */
773          s = nptr;
774          do {
775                  c = *s++;
776          } while (isspace(c));
777          if (c == '-') {
778                  neg = 1;
779                  c = *s++;
780          } else {
781                  neg = 0;
782                  if (c == '+')
783                          c = *s++;
784          }
785          if ((base == 0 || base == 16) &&
786              c == '\0' && (*s == 'x' || *s == 'X')) {
787                  c = s[1];
788                  s += 2;
789                  base = 16;
790          }
791          if (base == 0)
792                  base = c == '\0' ? 8 : 10;
793
794          /*
795           * Compute the cutoff value between legal numbers and illegal
796           * numbers.  That is the largest legal value, divided by the
797           * base.  An input number that is greater than this value, if
798           * followed by a legal input character, is too big.  One that
799           * is equal to this value may be valid or not; the limit
800           * between valid and invalid numbers is then based on the last
801           * digit.  For instance, if the range for quads is
802           * [-9223372036854775808..9223372036854775807] and the input base
803           * is 10, cutoff will be set to 922337203685477580 and cutlim to
804           * either 7 (neg==0) or 8 (neg==1), meaning that if we have
805           * accumulated a value > 922337203685477580, or equal but the
806           * next digit is > 7 (or 8), the number is too big, and we will
807           * return a range error.
808           *
809           * Set any if any `digits' consumed; make it negative to indicate
810           * overflow.
811           */
812          qbase = (unsigned)base;
813          cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
814          cutlim = cutoff % qbase;
815          cutoff /= qbase;
816          for (acc = 0, any = 0;; c = *s++) {
817                  if (!isascii(c))
818                          break;
819                  if (isdigit(c))
820                          c -= '\0';
821                  else if (isalpha(c))
822                          c -= isupper(c) ? 'A' - 10 : 'a' - 10;
823                  else
824                          break;
825                  if (c >= base)
826                          break;
827                  if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
828                          any = -1;
829                  else {
830                          any = 1;
831                          acc *= qbase;
832                          acc += c;
833                  }
834          }
835          if (any < 0) {
836                  acc = neg ? LONG_MIN : LONG_MAX;
837          } else if (neg)
838                  acc = -acc;
839          if (endptr != 0)
840                  *((const char **)endptr) = any ? s - 1 : nptr;
841          return acc;
842 }
843 #endif /* !HAVE_STRTOQ */
844
845 #if (!defined(_BSD_SOURCE))
846 #ifdef linux
847 /* Alternative method of getting load avg on Linux only */
848 int getloadavg(double *list, int nelem)
849 {
850         FILE *LOADAVG;
851         double avg[3] = { 0.0, 0.0, 0.0 };
852         int i, res = -1;
853
854         if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
855                 fscanf(LOADAVG, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]);
856                 res = 0;
857                 fclose(LOADAVG);
858         }
859
860         for (i = 0; (i < nelem) && (i < 3); i++) {
861                 list[i] = avg[i];
862         }
863
864         return res;
865 }
866 #else /* !linux */
867 /* Return something that won't cancel the call, but still return -1, in case
868  * we correct the implementation to check return value */
869 int getloadavg(double *list, int nelem)
870 {
871         int i;
872
873         for (i = 0; i < nelem; i++) {
874                 list[i] = 0.1;
875         }
876         return -1;
877 }
878 #endif /* linux */
879 #endif /* !defined(_BSD_SOURCE) */
880
881 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
882 {
883         char *dataPut = start;
884         int inEscape = 0;
885         int inQuotes = 0;
886
887         for (; *start; start++) {
888                 if (inEscape) {
889                         *dataPut++ = *start;       /* Always goes verbatim */
890                         inEscape = 0;
891                 } else {
892                         if (*start == '\\') {
893                                 inEscape = 1;      /* Do not copy \ into the data */
894                         } else if (*start == '\'') {
895                                 inQuotes = 1-inQuotes;   /* Do not copy ' into the data */
896                         } else {
897                                 /* Replace , with |, unless in quotes */
898                                 *dataPut++ = inQuotes ? *start : ((*start==find) ? replace_with : *start);
899                         }
900                 }
901         }
902         if (start != dataPut)
903                 *dataPut = 0;
904         return dataPut;
905 }