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