Merged revisions 77867 via svnmerge from
[asterisk/asterisk.git] / main / utils.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, 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 "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include <ctype.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42
43 #ifdef HAVE_DEV_URANDOM
44 #include <fcntl.h>
45 #endif
46
47 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in lock.h if required */
48 #include "asterisk/lock.h"
49 #include "asterisk/io.h"
50 #include "asterisk/logger.h"
51 #include "asterisk/md5.h"
52 #include "asterisk/sha1.h"
53 #include "asterisk/options.h"
54
55 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
56 #include "asterisk/strings.h"
57
58 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
59 #include "asterisk/time.h"
60
61 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
62 #include "asterisk/stringfields.h"
63
64 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
65 #include "asterisk/utils.h"
66
67 #define AST_API_MODULE
68 #include "asterisk/threadstorage.h"
69
70 static char base64[64];
71 static char b2a[256];
72
73 AST_THREADSTORAGE(inet_ntoa_buf);
74
75 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
76
77 #define ERANGE 34       /*!< duh? ERANGE value copied from web... */
78 #undef gethostbyname
79
80 AST_MUTEX_DEFINE_STATIC(__mutex);
81
82 /*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
83 \note This
84 routine is derived from code originally written and placed in the public 
85 domain by Enzo Michelangeli <em@em.no-ip.com> */
86
87 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
88                                 size_t buflen, struct hostent **result, 
89                                 int *h_errnop) 
90 {
91         int hsave;
92         struct hostent *ph;
93         ast_mutex_lock(&__mutex); /* begin critical area */
94         hsave = h_errno;
95
96         ph = gethostbyname(name);
97         *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
98         if (ph == NULL) {
99                 *result = NULL;
100         } else {
101                 char **p, **q;
102                 char *pbuf;
103                 int nbytes=0;
104                 int naddr=0, naliases=0;
105                 /* determine if we have enough space in buf */
106
107                 /* count how many addresses */
108                 for (p = ph->h_addr_list; *p != 0; p++) {
109                         nbytes += ph->h_length; /* addresses */
110                         nbytes += sizeof(*p); /* pointers */
111                         naddr++;
112                 }
113                 nbytes += sizeof(*p); /* one more for the terminating NULL */
114
115                 /* count how many aliases, and total length of strings */
116                 for (p = ph->h_aliases; *p != 0; p++) {
117                         nbytes += (strlen(*p)+1); /* aliases */
118                         nbytes += sizeof(*p);  /* pointers */
119                         naliases++;
120                 }
121                 nbytes += sizeof(*p); /* one more for the terminating NULL */
122
123                 /* here nbytes is the number of bytes required in buffer */
124                 /* as a terminator must be there, the minimum value is ph->h_length */
125                 if (nbytes > buflen) {
126                         *result = NULL;
127                         ast_mutex_unlock(&__mutex); /* end critical area */
128                         return ERANGE; /* not enough space in buf!! */
129                 }
130
131                 /* There is enough space. Now we need to do a deep copy! */
132                 /* Allocation in buffer:
133                         from [0] to [(naddr-1) * sizeof(*p)]:
134                         pointers to addresses
135                         at [naddr * sizeof(*p)]:
136                         NULL
137                         from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
138                         pointers to aliases
139                         at [(naddr+naliases+1) * sizeof(*p)]:
140                         NULL
141                         then naddr addresses (fixed length), and naliases aliases (asciiz).
142                 */
143
144                 *ret = *ph;   /* copy whole structure (not its address!) */
145
146                 /* copy addresses */
147                 q = (char **)buf; /* pointer to pointers area (type: char **) */
148                 ret->h_addr_list = q; /* update pointer to address list */
149                 pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
150                 for (p = ph->h_addr_list; *p != 0; p++) {
151                         memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
152                         *q++ = pbuf; /* the pointer is the one inside buf... */
153                         pbuf += ph->h_length; /* advance pbuf */
154                 }
155                 *q++ = NULL; /* address list terminator */
156
157                 /* copy aliases */
158                 ret->h_aliases = q; /* update pointer to aliases list */
159                 for (p = ph->h_aliases; *p != 0; p++) {
160                         strcpy(pbuf, *p); /* copy alias strings */
161                         *q++ = pbuf; /* the pointer is the one inside buf... */
162                         pbuf += strlen(*p); /* advance pbuf */
163                         *pbuf++ = 0; /* string terminator */
164                 }
165                 *q++ = NULL; /* terminator */
166
167                 strcpy(pbuf, ph->h_name); /* copy alias strings */
168                 ret->h_name = pbuf;
169                 pbuf += strlen(ph->h_name); /* advance pbuf */
170                 *pbuf++ = 0; /* string terminator */
171
172                 *result = ret;  /* and let *result point to structure */
173
174         }
175         h_errno = hsave;  /* restore h_errno */
176         ast_mutex_unlock(&__mutex); /* end critical area */
177
178         return (*result == NULL); /* return 0 on success, non-zero on error */
179 }
180
181
182 #endif
183
184 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the 
185    standard gethostbyname (which is not thread safe)
186 */
187 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
188 {
189         int res;
190         int herrno;
191         int dots=0;
192         const char *s;
193         struct hostent *result = NULL;
194         /* Although it is perfectly legitimate to lookup a pure integer, for
195            the sake of the sanity of people who like to name their peers as
196            integers, we break with tradition and refuse to look up a
197            pure integer */
198         s = host;
199         res = 0;
200         while (s && *s) {
201                 if (*s == '.')
202                         dots++;
203                 else if (!isdigit(*s))
204                         break;
205                 s++;
206         }
207         if (!s || !*s) {
208                 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
209                 if (dots != 3)
210                         return NULL;
211                 memset(hp, 0, sizeof(struct ast_hostent));
212                 hp->hp.h_addrtype = AF_INET;
213                 hp->hp.h_addr_list = (void *) hp->buf;
214                 hp->hp.h_addr = hp->buf + sizeof(void *);
215                 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
216                         return &hp->hp;
217                 return NULL;
218                 
219         }
220 #ifdef HAVE_GETHOSTBYNAME_R_5
221         result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
222
223         if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
224                 return NULL;
225 #else
226         res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
227
228         if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
229                 return NULL;
230 #endif
231         return &hp->hp;
232 }
233
234
235
236 AST_MUTEX_DEFINE_STATIC(test_lock);
237 AST_MUTEX_DEFINE_STATIC(test_lock2);
238 static pthread_t test_thread; 
239 static int lock_count = 0;
240 static int test_errors = 0;
241
242 /*! \brief This is a regression test for recursive mutexes.
243    test_for_thread_safety() will return 0 if recursive mutex locks are
244    working properly, and non-zero if they are not working properly. */
245 static void *test_thread_body(void *data) 
246
247         ast_mutex_lock(&test_lock);
248         lock_count += 10;
249         if (lock_count != 10) 
250                 test_errors++;
251         ast_mutex_lock(&test_lock);
252         lock_count += 10;
253         if (lock_count != 20) 
254                 test_errors++;
255         ast_mutex_lock(&test_lock2);
256         ast_mutex_unlock(&test_lock);
257         lock_count -= 10;
258         if (lock_count != 10) 
259                 test_errors++;
260         ast_mutex_unlock(&test_lock);
261         lock_count -= 10;
262         ast_mutex_unlock(&test_lock2);
263         if (lock_count != 0) 
264                 test_errors++;
265         return NULL;
266
267
268 int test_for_thread_safety(void)
269
270         ast_mutex_lock(&test_lock2);
271         ast_mutex_lock(&test_lock);
272         lock_count += 1;
273         ast_mutex_lock(&test_lock);
274         lock_count += 1;
275         ast_pthread_create(&test_thread, NULL, test_thread_body, NULL); 
276         usleep(100);
277         if (lock_count != 2) 
278                 test_errors++;
279         ast_mutex_unlock(&test_lock);
280         lock_count -= 1;
281         usleep(100); 
282         if (lock_count != 1) 
283                 test_errors++;
284         ast_mutex_unlock(&test_lock);
285         lock_count -= 1;
286         if (lock_count != 0) 
287                 test_errors++;
288         ast_mutex_unlock(&test_lock2);
289         usleep(100);
290         if (lock_count != 0) 
291                 test_errors++;
292         pthread_join(test_thread, NULL);
293         return(test_errors);          /* return 0 on success. */
294 }
295
296 /*! \brief Produce 32 char MD5 hash of value. */
297 void ast_md5_hash(char *output, char *input)
298 {
299         struct MD5Context md5;
300         unsigned char digest[16];
301         char *ptr;
302         int x;
303
304         MD5Init(&md5);
305         MD5Update(&md5, (unsigned char *)input, strlen(input));
306         MD5Final(digest, &md5);
307         ptr = output;
308         for (x = 0; x < 16; x++)
309                 ptr += sprintf(ptr, "%2.2x", digest[x]);
310 }
311
312 /*! \brief Produce 40 char SHA1 hash of value. */
313 void ast_sha1_hash(char *output, char *input)
314 {
315         struct SHA1Context sha;
316         char *ptr;
317         int x;
318         uint8_t Message_Digest[20];
319
320         SHA1Reset(&sha);
321         
322         SHA1Input(&sha, (const unsigned char *) input, strlen(input));
323
324         SHA1Result(&sha, Message_Digest);
325         ptr = output;
326         for (x = 0; x < 20; x++)
327                 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
328 }
329
330 /*! \brief decode BASE64 encoded text */
331 int ast_base64decode(unsigned char *dst, const char *src, int max)
332 {
333         int cnt = 0;
334         unsigned int byte = 0;
335         unsigned int bits = 0;
336         int incnt = 0;
337         while (*src && (cnt < max)) {
338                 /* Shift in 6 bits of input */
339                 byte <<= 6;
340                 byte |= (b2a[(int)(*src)]) & 0x3f;
341                 bits += 6;
342                 src++;
343                 incnt++;
344                 /* If we have at least 8 bits left over, take that character 
345                    off the top */
346                 if (bits >= 8)  {
347                         bits -= 8;
348                         *dst = (byte >> bits) & 0xff;
349                         dst++;
350                         cnt++;
351                 }
352         }
353         /* Dont worry about left over bits, they're extra anyway */
354         return cnt;
355 }
356
357 /*! \brief encode text to BASE64 coding */
358 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
359 {
360         int cnt = 0;
361         int col = 0;
362         unsigned int byte = 0;
363         int bits = 0;
364         int cntin = 0;
365         /* Reserve space for null byte at end of string */
366         max--;
367         while ((cntin < srclen) && (cnt < max)) {
368                 byte <<= 8;
369                 byte |= *(src++);
370                 bits += 8;
371                 cntin++;
372                 if ((bits == 24) && (cnt + 4 <= max)) {
373                         *dst++ = base64[(byte >> 18) & 0x3f];
374                         *dst++ = base64[(byte >> 12) & 0x3f];
375                         *dst++ = base64[(byte >> 6) & 0x3f];
376                         *dst++ = base64[byte & 0x3f];
377                         cnt += 4;
378                         col += 4;
379                         bits = 0;
380                         byte = 0;
381                 }
382                 if (linebreaks && (cnt < max) && (col == 64)) {
383                         *dst++ = '\n';
384                         cnt++;
385                         col = 0;
386                 }
387         }
388         if (bits && (cnt + 4 <= max)) {
389                 /* Add one last character for the remaining bits, 
390                    padding the rest with 0 */
391                 byte <<= 24 - bits;
392                 *dst++ = base64[(byte >> 18) & 0x3f];
393                 *dst++ = base64[(byte >> 12) & 0x3f];
394                 if (bits == 16)
395                         *dst++ = base64[(byte >> 6) & 0x3f];
396                 else
397                         *dst++ = '=';
398                 *dst++ = '=';
399                 cnt += 4;
400         }
401         if (linebreaks && (cnt < max)) {
402                 *dst++ = '\n';
403                 cnt++;
404         }
405         *dst = '\0';
406         return cnt;
407 }
408
409 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
410 {
411         return ast_base64encode_full(dst, src, srclen, max, 0);
412 }
413
414 static void base64_init(void)
415 {
416         int x;
417         memset(b2a, -1, sizeof(b2a));
418         /* Initialize base-64 Conversion table */
419         for (x = 0; x < 26; x++) {
420                 /* A-Z */
421                 base64[x] = 'A' + x;
422                 b2a['A' + x] = x;
423                 /* a-z */
424                 base64[x + 26] = 'a' + x;
425                 b2a['a' + x] = x + 26;
426                 /* 0-9 */
427                 if (x < 10) {
428                         base64[x + 52] = '0' + x;
429                         b2a['0' + x] = x + 52;
430                 }
431         }
432         base64[62] = '+';
433         base64[63] = '/';
434         b2a[(int)'+'] = 62;
435         b2a[(int)'/'] = 63;
436 }
437
438 /*! \brief  ast_uri_encode: Turn text string to URI-encoded %XX version
439 \note   At this point, we're converting from ISO-8859-x (8-bit), not UTF8
440         as in the SIP protocol spec 
441         If doreserved == 1 we will convert reserved characters also.
442         RFC 2396, section 2.4
443         outbuf needs to have more memory allocated than the instring
444         to have room for the expansion. Every char that is converted
445         is replaced by three ASCII characters.
446
447         Note: The doreserved option is needed for replaces header in
448         SIP transfers.
449 */
450 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved) 
451 {
452         char *reserved = ";/?:@&=+$, "; /* Reserved chars */
453
454         const char *ptr  = string;      /* Start with the string */
455         char *out = NULL;
456         char *buf = NULL;
457
458         ast_copy_string(outbuf, string, buflen);
459
460         /* If there's no characters to convert, just go through and don't do anything */
461         while (*ptr) {
462                 if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
463                         /* Oops, we need to start working here */
464                         if (!buf) {
465                                 buf = outbuf;
466                                 out = buf + (ptr - string) ;    /* Set output ptr */
467                         }
468                         out += sprintf(out, "%%%02x", (unsigned char) *ptr);
469                 } else if (buf) {
470                         *out = *ptr;    /* Continue copying the string */
471                         out++;
472                 } 
473                 ptr++;
474         }
475         if (buf)
476                 *out = '\0';
477         return outbuf;
478 }
479
480 /*! \brief  ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)  */
481 void ast_uri_decode(char *s) 
482 {
483         char *o;
484         unsigned int tmp;
485
486         for (o = s; *s; s++, o++) {
487                 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
488                         /* have '%', two chars and correct parsing */
489                         *o = tmp;
490                         s += 2; /* Will be incremented once more when we break out */
491                 } else /* all other cases, just copy */
492                         *o = *s;
493         }
494         *o = '\0';
495 }
496
497 /*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
498 const char *ast_inet_ntoa(struct in_addr ia)
499 {
500         char *buf;
501
502         if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
503                 return "";
504
505         return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
506 }
507
508 #ifdef HAVE_DEV_URANDOM
509 static int dev_urandom_fd;
510 #endif
511
512 int ast_utils_init(void)
513 {
514 #ifdef HAVE_DEV_URANDOM
515         dev_urandom_fd = open("/dev/urandom", O_RDONLY);
516 #endif
517         base64_init();
518         return 0;
519 }
520
521 #ifndef __linux__
522 #undef pthread_create /* For ast_pthread_create function only */
523 #endif /* !__linux__ */
524
525 #if !defined(LOW_MEMORY)
526 /*
527  * support for 'show threads'. The start routine is wrapped by
528  * dummy_start(), so that ast_register_thread() and
529  * ast_unregister_thread() know the thread identifier.
530  */
531 struct thr_arg {
532         void *(*start_routine)(void *);
533         void *data;
534         char *name;
535 };
536
537 /*
538  * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
539  * are odd macros which start and end a block, so they _must_ be
540  * used in pairs (the latter with a '1' argument to call the
541  * handler on exit.
542  * On BSD we don't need this, but we keep it for compatibility.
543  */
544 static void *dummy_start(void *data)
545 {
546         void *ret;
547         struct thr_arg a = *((struct thr_arg *) data);  /* make a local copy */
548
549         /* note that even though data->name is a pointer to allocated memory,
550            we are not freeing it here because ast_register_thread is going to
551            keep a copy of the pointer and then ast_unregister_thread will
552            free the memory
553         */
554         ast_free(data);
555         ast_register_thread(a.name);
556         pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
557         ret = a.start_routine(a.data);
558         pthread_cleanup_pop(1);
559
560         return ret;
561 }
562
563 #endif /* !LOW_MEMORY */
564
565 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
566                              void *data, size_t stacksize, const char *file, const char *caller,
567                              int line, const char *start_fn)
568 {
569 #if !defined(LOW_MEMORY)
570         struct thr_arg *a;
571 #endif
572
573         if (!attr) {
574                 attr = alloca(sizeof(*attr));
575                 pthread_attr_init(attr);
576         }
577
578 #ifdef __linux__
579         /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
580            which is kind of useless. Change this here to
581            PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
582            priority will propagate down to new threads by default.
583            This does mean that callers cannot set a different priority using
584            PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
585            the priority afterwards with pthread_setschedparam(). */
586         if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
587                 ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
588 #endif
589
590         if (!stacksize)
591                 stacksize = AST_STACKSIZE;
592
593         if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
594                 ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
595
596 #if !defined(LOW_MEMORY)
597         if ((a = ast_malloc(sizeof(*a)))) {
598                 a->start_routine = start_routine;
599                 a->data = data;
600                 start_routine = dummy_start;
601                 asprintf(&a->name, "%-20s started at [%5d] %s %s()",
602                          start_fn, line, file, caller);
603                 data = a;
604         }
605 #endif /* !LOW_MEMORY */
606
607         return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
608 }
609
610
611 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
612                              void *data, size_t stacksize, const char *file, const char *caller,
613                              int line, const char *start_fn)
614 {
615         unsigned char attr_destroy = 0;
616         int res;
617
618         if (!attr) {
619                 attr = alloca(sizeof(*attr));
620                 pthread_attr_init(attr);
621                 attr_destroy = 1;
622         }
623
624         if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
625                 ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
626
627         res = ast_pthread_create_stack(thread, attr, start_routine, data, 
628                                        stacksize, file, caller, line, start_fn);
629
630         if (attr_destroy)
631                 pthread_attr_destroy(attr);
632
633         return res;
634 }
635
636 int ast_wait_for_input(int fd, int ms)
637 {
638         struct pollfd pfd[1];
639         memset(pfd, 0, sizeof(pfd));
640         pfd[0].fd = fd;
641         pfd[0].events = POLLIN|POLLPRI;
642         return poll(pfd, 1, ms);
643 }
644
645 /*!
646  * Try to write string, but wait no more than ms milliseconds before timing out.
647  *
648  * \note The code assumes that the file descriptor has NONBLOCK set,
649  * so there is only one system call made to do a write, unless we actually
650  * have a need to wait.  This way, we get better performance.
651  * If the descriptor is blocking, all assumptions on the guaranteed
652  * detail do not apply anymore.
653  * Also note that in the current implementation, the delay is per-write,
654  * so you still have no guarantees, anyways.
655  * Fortunately the routine is only used in a few places (cli.c, manager.c,
656  * res_agi.c) so it is reasonably easy to check how it behaves there.
657  *
658  * XXX We either need to fix the code, or fix the documentation.
659  */
660 int ast_carefulwrite(int fd, char *s, int len, int timeoutms) 
661 {
662         /* Try to write string, but wait no more than ms milliseconds
663            before timing out */
664         int res = 0;
665         struct pollfd fds[1];
666         while (len) {
667                 res = write(fd, s, len);
668                 if ((res < 0) && (errno != EAGAIN)) {
669                         return -1;
670                 }
671                 if (res < 0)
672                         res = 0;
673                 len -= res;
674                 s += res;
675                 res = 0;
676                 if (len) {
677                         fds[0].fd = fd;
678                         fds[0].events = POLLOUT;
679                         /* Wait until writable again */
680                         res = poll(fds, 1, timeoutms);
681                         if (res < 1)
682                                 return -1;
683                 }
684         }
685         return res;
686 }
687
688 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
689 {
690         char *e;
691         char *q;
692
693         s = ast_strip(s);
694         if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
695                 e = s + strlen(s) - 1;
696                 if (*e == *(end_quotes + (q - beg_quotes))) {
697                         s++;
698                         *e = '\0';
699                 }
700         }
701
702         return s;
703 }
704
705 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
706 {
707         int result;
708
709         if (!buffer || !*buffer || !space || !*space)
710                 return -1;
711
712         result = vsnprintf(*buffer, *space, fmt, ap);
713
714         if (result < 0)
715                 return -1;
716         else if (result > *space)
717                 result = *space;
718
719         *buffer += result;
720         *space -= result;
721         return 0;
722 }
723
724 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
725 {
726         va_list ap;
727         int result;
728
729         va_start(ap, fmt);
730         result = ast_build_string_va(buffer, space, fmt, ap);
731         va_end(ap);
732
733         return result;
734 }
735
736 int ast_true(const char *s)
737 {
738         if (ast_strlen_zero(s))
739                 return 0;
740
741         /* Determine if this is a true value */
742         if (!strcasecmp(s, "yes") ||
743             !strcasecmp(s, "true") ||
744             !strcasecmp(s, "y") ||
745             !strcasecmp(s, "t") ||
746             !strcasecmp(s, "1") ||
747             !strcasecmp(s, "on"))
748                 return -1;
749
750         return 0;
751 }
752
753 int ast_false(const char *s)
754 {
755         if (ast_strlen_zero(s))
756                 return 0;
757
758         /* Determine if this is a false value */
759         if (!strcasecmp(s, "no") ||
760             !strcasecmp(s, "false") ||
761             !strcasecmp(s, "n") ||
762             !strcasecmp(s, "f") ||
763             !strcasecmp(s, "0") ||
764             !strcasecmp(s, "off"))
765                 return -1;
766
767         return 0;
768 }
769
770 #define ONE_MILLION     1000000
771 /*
772  * put timeval in a valid range. usec is 0..999999
773  * negative values are not allowed and truncated.
774  */
775 static struct timeval tvfix(struct timeval a)
776 {
777         if (a.tv_usec >= ONE_MILLION) {
778                 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
779                         a.tv_sec, (long int) a.tv_usec);
780                 a.tv_sec += a.tv_usec / ONE_MILLION;
781                 a.tv_usec %= ONE_MILLION;
782         } else if (a.tv_usec < 0) {
783                 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
784                         a.tv_sec, (long int) a.tv_usec);
785                 a.tv_usec = 0;
786         }
787         return a;
788 }
789
790 struct timeval ast_tvadd(struct timeval a, struct timeval b)
791 {
792         /* consistency checks to guarantee usec in 0..999999 */
793         a = tvfix(a);
794         b = tvfix(b);
795         a.tv_sec += b.tv_sec;
796         a.tv_usec += b.tv_usec;
797         if (a.tv_usec >= ONE_MILLION) {
798                 a.tv_sec++;
799                 a.tv_usec -= ONE_MILLION;
800         }
801         return a;
802 }
803
804 struct timeval ast_tvsub(struct timeval a, struct timeval b)
805 {
806         /* consistency checks to guarantee usec in 0..999999 */
807         a = tvfix(a);
808         b = tvfix(b);
809         a.tv_sec -= b.tv_sec;
810         a.tv_usec -= b.tv_usec;
811         if (a.tv_usec < 0) {
812                 a.tv_sec-- ;
813                 a.tv_usec += ONE_MILLION;
814         }
815         return a;
816 }
817 #undef ONE_MILLION
818
819 /*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
820  * BSD libc (and others) do not. */
821
822 #ifndef linux
823 AST_MUTEX_DEFINE_STATIC(randomlock);
824 #endif
825
826 long int ast_random(void)
827 {
828         long int res;
829 #ifdef HAVE_DEV_URANDOM
830         if (dev_urandom_fd >= 0) {
831                 int read_res = read(dev_urandom_fd, &res, sizeof(res));
832                 if (read_res > 0)
833                         return labs(res);
834         }
835 #endif
836 #ifdef linux
837         res = random();
838 #else
839         ast_mutex_lock(&randomlock);
840         res = random();
841         ast_mutex_unlock(&randomlock);
842 #endif
843         return res;
844 }
845
846 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
847 {
848         char *dataPut = start;
849         int inEscape = 0;
850         int inQuotes = 0;
851
852         for (; *start; start++) {
853                 if (inEscape) {
854                         *dataPut++ = *start;       /* Always goes verbatim */
855                         inEscape = 0;
856                 } else {
857                         if (*start == '\\') {
858                                 inEscape = 1;      /* Do not copy \ into the data */
859                         } else if (*start == '\'') {
860                                 inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
861                         } else {
862                                 /* Replace , with |, unless in quotes */
863                                 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
864                         }
865                 }
866         }
867         if (start != dataPut)
868                 *dataPut = 0;
869         return dataPut;
870 }
871
872 void ast_join(char *s, size_t len, char * const w[])
873 {
874         int x, ofs = 0;
875         const char *src;
876
877         /* Join words into a string */
878         if (!s)
879                 return;
880         for (x = 0; ofs < len && w[x]; x++) {
881                 if (x > 0)
882                         s[ofs++] = ' ';
883                 for (src = w[x]; *src && ofs < len; src++)
884                         s[ofs++] = *src;
885         }
886         if (ofs == len)
887                 ofs--;
888         s[ofs] = '\0';
889 }
890
891 const char __ast_string_field_empty[] = "";
892
893 static int add_string_pool(struct ast_string_field_mgr *mgr, size_t size)
894 {
895         struct ast_string_field_pool *pool;
896
897         if (!(pool = ast_calloc(1, sizeof(*pool) + size)))
898                 return -1;
899         
900         pool->prev = mgr->pool;
901         mgr->pool = pool;
902         mgr->size = size;
903         mgr->space = size;
904         mgr->used = 0;
905
906         return 0;
907 }
908
909 int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
910                             ast_string_field *fields, int num_fields)
911 {
912         int index;
913
914         if (add_string_pool(mgr, size))
915                 return -1;
916
917         for (index = 0; index < num_fields; index++)
918                 fields[index] = __ast_string_field_empty;
919
920         return 0;
921 }
922
923 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
924                                                 ast_string_field *fields, int num_fields)
925 {
926         char *result = NULL;
927
928         if (__builtin_expect(needed > mgr->space, 0)) {
929                 size_t new_size = mgr->size * 2;
930
931                 while (new_size < needed)
932                         new_size *= 2;
933
934                 if (add_string_pool(mgr, new_size))
935                         return NULL;
936         }
937
938         result = mgr->pool->base + mgr->used;
939         mgr->used += needed;
940         mgr->space -= needed;
941         return result;
942 }
943
944 void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
945                                     ast_string_field *fields, int num_fields,
946                                     int index, const char *format, va_list ap1, va_list ap2)
947 {
948         size_t needed;
949
950         needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
951
952         va_end(ap1);
953
954         if (needed > mgr->space) {
955                 size_t new_size = mgr->size * 2;
956
957                 while (new_size < needed)
958                         new_size *= 2;
959
960                 if (add_string_pool(mgr, new_size))
961                         return;
962
963                 vsprintf(mgr->pool->base + mgr->used, format, ap2);
964         }
965
966         fields[index] = mgr->pool->base + mgr->used;
967         mgr->used += needed;
968         mgr->space -= needed;
969 }
970
971 void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
972                                     ast_string_field *fields, int num_fields,
973                                     int index, const char *format, ...)
974 {
975         va_list ap1, ap2;
976
977         va_start(ap1, format);
978         va_start(ap2, format);          /* va_copy does not exist on FreeBSD */
979
980         __ast_string_field_index_build_va(mgr, fields, num_fields, index, format, ap1, ap2);
981
982         va_end(ap1);
983         va_end(ap2);
984 }
985
986 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
987
988 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
989 {
990         int ret;
991         ast_mutex_lock(&fetchadd_m);
992         ret = *p;
993         *p += v;
994         ast_mutex_unlock(&fetchadd_m);
995         return ret;
996 }
997
998 /*! \brief
999  * get values from config variables.
1000  */
1001 int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
1002 {
1003         long double dtv = 0.0;
1004         int scanned;
1005
1006         if (dst == NULL)
1007                 return -1;
1008
1009         *dst = _default;
1010
1011         if (ast_strlen_zero(src))
1012                 return -1;
1013
1014         /* only integer at the moment, but one day we could accept more formats */
1015         if (sscanf(src, "%Lf%n", &dtv, &scanned) > 0) {
1016                 dst->tv_sec = dtv;
1017                 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
1018                 if (consumed)
1019                         *consumed = scanned;
1020                 return 0;
1021         } else
1022                 return -1;
1023 }
1024
1025 /*! \brief
1026  * get values from config variables.
1027  */
1028 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
1029 {
1030         long t;
1031         int scanned;
1032
1033         if (dst == NULL)
1034                 return -1;
1035
1036         *dst = _default;
1037
1038         if (ast_strlen_zero(src))
1039                 return -1;
1040
1041         /* only integer at the moment, but one day we could accept more formats */
1042         if (sscanf(src, "%ld%n", &t, &scanned) == 1) {
1043                 *dst = t;
1044                 if (consumed)
1045                         *consumed = scanned;
1046                 return 0;
1047         } else
1048                 return -1;
1049 }
1050
1051 /*!
1052  * core handler for dynamic strings.
1053  * This is not meant to be called directly, but rather through the
1054  * various wrapper macros
1055  *      ast_str_set(...)
1056  *      ast_str_append(...)
1057  *      ast_str_set_va(...)
1058  *      ast_str_append_va(...)
1059  */
1060 int __ast_str_helper(struct ast_str **buf, size_t max_len,
1061         int append, const char *fmt, va_list ap)
1062 {
1063         int res, need;
1064         int offset = (append && (*buf)->len) ? (*buf)->used : 0;
1065
1066         if (max_len < 0)
1067                 max_len = (*buf)->len;  /* don't exceed the allocated space */
1068         /*
1069          * Ask vsnprintf how much space we need. Remember that vsnprintf
1070          * does not count the final '\0' so we must add 1.
1071          */
1072         res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap);
1073
1074         need = res + offset + 1;
1075         /*
1076          * If there is not enough space and we are below the max length,
1077          * reallocate the buffer and return a message telling to retry.
1078          */
1079         if (need > (*buf)->len && (max_len == 0 || (*buf)->len < max_len) ) {
1080                 if (max_len && max_len < need)  /* truncate as needed */
1081                         need = max_len;
1082                 else if (max_len == 0)  /* if unbounded, give more room for next time */
1083                         need += 16 + need/4;
1084                 if (0)  /* debugging */
1085                         ast_verbose("extend from %d to %d\n", (int)(*buf)->len, need);
1086                 if (ast_str_make_space(buf, need)) {
1087                         ast_verbose("failed to extend from %d to %d\n", (int)(*buf)->len, need);
1088                         return AST_DYNSTR_BUILD_FAILED;
1089                 }
1090                 (*buf)->str[offset] = '\0';     /* Truncate the partial write. */
1091
1092                 /* va_end() and va_start() must be done before calling
1093                  * vsnprintf() again. */
1094                 return AST_DYNSTR_BUILD_RETRY;
1095         }
1096         /* update space used, keep in mind the truncation */
1097         (*buf)->used = (res + offset > (*buf)->len) ? (*buf)->len : res + offset;
1098
1099         return res;
1100 }
1101
1102 void ast_enable_packet_fragmentation(int sock)
1103 {
1104 #if defined(HAVE_IP_MTU_DISCOVER)
1105         int val = IP_PMTUDISC_DONT;
1106         
1107         if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
1108                 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
1109 #endif /* HAVE_IP_MTU_DISCOVER */
1110 }
1111
1112 int ast_mkdir(const char *path, int mode)
1113 {
1114         char *ptr;
1115         int len = strlen(path), count = 0, x, piececount = 0;
1116         char *tmp = ast_strdupa(path);
1117         char **pieces;
1118         char *fullpath = alloca(len + 1);
1119         int res = 0;
1120
1121         for (ptr = tmp; *ptr; ptr++) {
1122                 if (*ptr == '/')
1123                         count++;
1124         }
1125
1126         /* Count the components to the directory path */
1127         pieces = alloca(count * sizeof(*pieces));
1128         for (ptr = tmp; *ptr; ptr++) {
1129                 if (*ptr == '/') {
1130                         *ptr = '\0';
1131                         pieces[piececount++] = ptr + 1;
1132                 }
1133         }
1134
1135         *fullpath = '\0';
1136         for (x = 0; x < piececount; x++) {
1137                 /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
1138                 strcat(fullpath, "/");
1139                 strcat(fullpath, pieces[x]);
1140                 res = mkdir(fullpath, mode);
1141                 if (res && errno != EEXIST)
1142                         return errno;
1143         }
1144         return 0;
1145 }
1146