79bfd5306adda34f24b6e0cc173ad65239ecc116
[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 #include "asterisk/cli.h"
55 #include "asterisk/linkedlists.h"
56
57 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
58 #include "asterisk/strings.h"
59
60 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
61 #include "asterisk/time.h"
62
63 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
64 #include "asterisk/stringfields.h"
65
66 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
67 #include "asterisk/utils.h"
68
69 #define AST_API_MODULE
70 #include "asterisk/threadstorage.h"
71
72 static char base64[64];
73 static char b2a[256];
74
75 AST_THREADSTORAGE(inet_ntoa_buf);
76
77 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
78
79 #define ERANGE 34       /*!< duh? ERANGE value copied from web... */
80 #undef gethostbyname
81
82 AST_MUTEX_DEFINE_STATIC(__mutex);
83
84 /*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
85 \note This
86 routine is derived from code originally written and placed in the public 
87 domain by Enzo Michelangeli <em@em.no-ip.com> */
88
89 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
90                                 size_t buflen, struct hostent **result, 
91                                 int *h_errnop) 
92 {
93         int hsave;
94         struct hostent *ph;
95         ast_mutex_lock(&__mutex); /* begin critical area */
96         hsave = h_errno;
97
98         ph = gethostbyname(name);
99         *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
100         if (ph == NULL) {
101                 *result = NULL;
102         } else {
103                 char **p, **q;
104                 char *pbuf;
105                 int nbytes=0;
106                 int naddr=0, naliases=0;
107                 /* determine if we have enough space in buf */
108
109                 /* count how many addresses */
110                 for (p = ph->h_addr_list; *p != 0; p++) {
111                         nbytes += ph->h_length; /* addresses */
112                         nbytes += sizeof(*p); /* pointers */
113                         naddr++;
114                 }
115                 nbytes += sizeof(*p); /* one more for the terminating NULL */
116
117                 /* count how many aliases, and total length of strings */
118                 for (p = ph->h_aliases; *p != 0; p++) {
119                         nbytes += (strlen(*p)+1); /* aliases */
120                         nbytes += sizeof(*p);  /* pointers */
121                         naliases++;
122                 }
123                 nbytes += sizeof(*p); /* one more for the terminating NULL */
124
125                 /* here nbytes is the number of bytes required in buffer */
126                 /* as a terminator must be there, the minimum value is ph->h_length */
127                 if (nbytes > buflen) {
128                         *result = NULL;
129                         ast_mutex_unlock(&__mutex); /* end critical area */
130                         return ERANGE; /* not enough space in buf!! */
131                 }
132
133                 /* There is enough space. Now we need to do a deep copy! */
134                 /* Allocation in buffer:
135                         from [0] to [(naddr-1) * sizeof(*p)]:
136                         pointers to addresses
137                         at [naddr * sizeof(*p)]:
138                         NULL
139                         from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
140                         pointers to aliases
141                         at [(naddr+naliases+1) * sizeof(*p)]:
142                         NULL
143                         then naddr addresses (fixed length), and naliases aliases (asciiz).
144                 */
145
146                 *ret = *ph;   /* copy whole structure (not its address!) */
147
148                 /* copy addresses */
149                 q = (char **)buf; /* pointer to pointers area (type: char **) */
150                 ret->h_addr_list = q; /* update pointer to address list */
151                 pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
152                 for (p = ph->h_addr_list; *p != 0; p++) {
153                         memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
154                         *q++ = pbuf; /* the pointer is the one inside buf... */
155                         pbuf += ph->h_length; /* advance pbuf */
156                 }
157                 *q++ = NULL; /* address list terminator */
158
159                 /* copy aliases */
160                 ret->h_aliases = q; /* update pointer to aliases list */
161                 for (p = ph->h_aliases; *p != 0; p++) {
162                         strcpy(pbuf, *p); /* copy alias strings */
163                         *q++ = pbuf; /* the pointer is the one inside buf... */
164                         pbuf += strlen(*p); /* advance pbuf */
165                         *pbuf++ = 0; /* string terminator */
166                 }
167                 *q++ = NULL; /* terminator */
168
169                 strcpy(pbuf, ph->h_name); /* copy alias strings */
170                 ret->h_name = pbuf;
171                 pbuf += strlen(ph->h_name); /* advance pbuf */
172                 *pbuf++ = 0; /* string terminator */
173
174                 *result = ret;  /* and let *result point to structure */
175
176         }
177         h_errno = hsave;  /* restore h_errno */
178         ast_mutex_unlock(&__mutex); /* end critical area */
179
180         return (*result == NULL); /* return 0 on success, non-zero on error */
181 }
182
183
184 #endif
185
186 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the 
187    standard gethostbyname (which is not thread safe)
188 */
189 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
190 {
191         int res;
192         int herrno;
193         int dots=0;
194         const char *s;
195         struct hostent *result = NULL;
196         /* Although it is perfectly legitimate to lookup a pure integer, for
197            the sake of the sanity of people who like to name their peers as
198            integers, we break with tradition and refuse to look up a
199            pure integer */
200         s = host;
201         res = 0;
202         while (s && *s) {
203                 if (*s == '.')
204                         dots++;
205                 else if (!isdigit(*s))
206                         break;
207                 s++;
208         }
209         if (!s || !*s) {
210                 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
211                 if (dots != 3)
212                         return NULL;
213                 memset(hp, 0, sizeof(struct ast_hostent));
214                 hp->hp.h_addrtype = AF_INET;
215                 hp->hp.h_addr_list = (void *) hp->buf;
216                 hp->hp.h_addr = hp->buf + sizeof(void *);
217                 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
218                         return &hp->hp;
219                 return NULL;
220                 
221         }
222 #ifdef HAVE_GETHOSTBYNAME_R_5
223         result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
224
225         if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
226                 return NULL;
227 #else
228         res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
229
230         if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
231                 return NULL;
232 #endif
233         return &hp->hp;
234 }
235
236
237
238 AST_MUTEX_DEFINE_STATIC(test_lock);
239 AST_MUTEX_DEFINE_STATIC(test_lock2);
240 static pthread_t test_thread; 
241 static int lock_count = 0;
242 static int test_errors = 0;
243
244 /*! \brief This is a regression test for recursive mutexes.
245    test_for_thread_safety() will return 0 if recursive mutex locks are
246    working properly, and non-zero if they are not working properly. */
247 static void *test_thread_body(void *data) 
248
249         ast_mutex_lock(&test_lock);
250         lock_count += 10;
251         if (lock_count != 10) 
252                 test_errors++;
253         ast_mutex_lock(&test_lock);
254         lock_count += 10;
255         if (lock_count != 20) 
256                 test_errors++;
257         ast_mutex_lock(&test_lock2);
258         ast_mutex_unlock(&test_lock);
259         lock_count -= 10;
260         if (lock_count != 10) 
261                 test_errors++;
262         ast_mutex_unlock(&test_lock);
263         lock_count -= 10;
264         ast_mutex_unlock(&test_lock2);
265         if (lock_count != 0) 
266                 test_errors++;
267         return NULL;
268
269
270 int test_for_thread_safety(void)
271
272         ast_mutex_lock(&test_lock2);
273         ast_mutex_lock(&test_lock);
274         lock_count += 1;
275         ast_mutex_lock(&test_lock);
276         lock_count += 1;
277         ast_pthread_create(&test_thread, NULL, test_thread_body, NULL); 
278         usleep(100);
279         if (lock_count != 2) 
280                 test_errors++;
281         ast_mutex_unlock(&test_lock);
282         lock_count -= 1;
283         usleep(100); 
284         if (lock_count != 1) 
285                 test_errors++;
286         ast_mutex_unlock(&test_lock);
287         lock_count -= 1;
288         if (lock_count != 0) 
289                 test_errors++;
290         ast_mutex_unlock(&test_lock2);
291         usleep(100);
292         if (lock_count != 0) 
293                 test_errors++;
294         pthread_join(test_thread, NULL);
295         return(test_errors);          /* return 0 on success. */
296 }
297
298 /*! \brief Produce 32 char MD5 hash of value. */
299 void ast_md5_hash(char *output, char *input)
300 {
301         struct MD5Context md5;
302         unsigned char digest[16];
303         char *ptr;
304         int x;
305
306         MD5Init(&md5);
307         MD5Update(&md5, (unsigned char *)input, strlen(input));
308         MD5Final(digest, &md5);
309         ptr = output;
310         for (x = 0; x < 16; x++)
311                 ptr += sprintf(ptr, "%2.2x", digest[x]);
312 }
313
314 /*! \brief Produce 40 char SHA1 hash of value. */
315 void ast_sha1_hash(char *output, char *input)
316 {
317         struct SHA1Context sha;
318         char *ptr;
319         int x;
320         uint8_t Message_Digest[20];
321
322         SHA1Reset(&sha);
323         
324         SHA1Input(&sha, (const unsigned char *) input, strlen(input));
325
326         SHA1Result(&sha, Message_Digest);
327         ptr = output;
328         for (x = 0; x < 20; x++)
329                 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
330 }
331
332 /*! \brief decode BASE64 encoded text */
333 int ast_base64decode(unsigned char *dst, const char *src, int max)
334 {
335         int cnt = 0;
336         unsigned int byte = 0;
337         unsigned int bits = 0;
338         int incnt = 0;
339         while (*src && (cnt < max)) {
340                 /* Shift in 6 bits of input */
341                 byte <<= 6;
342                 byte |= (b2a[(int)(*src)]) & 0x3f;
343                 bits += 6;
344                 src++;
345                 incnt++;
346                 /* If we have at least 8 bits left over, take that character 
347                    off the top */
348                 if (bits >= 8)  {
349                         bits -= 8;
350                         *dst = (byte >> bits) & 0xff;
351                         dst++;
352                         cnt++;
353                 }
354         }
355         /* Dont worry about left over bits, they're extra anyway */
356         return cnt;
357 }
358
359 /*! \brief encode text to BASE64 coding */
360 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
361 {
362         int cnt = 0;
363         int col = 0;
364         unsigned int byte = 0;
365         int bits = 0;
366         int cntin = 0;
367         /* Reserve space for null byte at end of string */
368         max--;
369         while ((cntin < srclen) && (cnt < max)) {
370                 byte <<= 8;
371                 byte |= *(src++);
372                 bits += 8;
373                 cntin++;
374                 if ((bits == 24) && (cnt + 4 <= max)) {
375                         *dst++ = base64[(byte >> 18) & 0x3f];
376                         *dst++ = base64[(byte >> 12) & 0x3f];
377                         *dst++ = base64[(byte >> 6) & 0x3f];
378                         *dst++ = base64[byte & 0x3f];
379                         cnt += 4;
380                         col += 4;
381                         bits = 0;
382                         byte = 0;
383                 }
384                 if (linebreaks && (cnt < max) && (col == 64)) {
385                         *dst++ = '\n';
386                         cnt++;
387                         col = 0;
388                 }
389         }
390         if (bits && (cnt + 4 <= max)) {
391                 /* Add one last character for the remaining bits, 
392                    padding the rest with 0 */
393                 byte <<= 24 - bits;
394                 *dst++ = base64[(byte >> 18) & 0x3f];
395                 *dst++ = base64[(byte >> 12) & 0x3f];
396                 if (bits == 16)
397                         *dst++ = base64[(byte >> 6) & 0x3f];
398                 else
399                         *dst++ = '=';
400                 *dst++ = '=';
401                 cnt += 4;
402         }
403         if (linebreaks && (cnt < max)) {
404                 *dst++ = '\n';
405                 cnt++;
406         }
407         *dst = '\0';
408         return cnt;
409 }
410
411 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
412 {
413         return ast_base64encode_full(dst, src, srclen, max, 0);
414 }
415
416 static void base64_init(void)
417 {
418         int x;
419         memset(b2a, -1, sizeof(b2a));
420         /* Initialize base-64 Conversion table */
421         for (x = 0; x < 26; x++) {
422                 /* A-Z */
423                 base64[x] = 'A' + x;
424                 b2a['A' + x] = x;
425                 /* a-z */
426                 base64[x + 26] = 'a' + x;
427                 b2a['a' + x] = x + 26;
428                 /* 0-9 */
429                 if (x < 10) {
430                         base64[x + 52] = '0' + x;
431                         b2a['0' + x] = x + 52;
432                 }
433         }
434         base64[62] = '+';
435         base64[63] = '/';
436         b2a[(int)'+'] = 62;
437         b2a[(int)'/'] = 63;
438 }
439
440 /*! \brief  ast_uri_encode: Turn text string to URI-encoded %XX version
441 \note   At this point, we're converting from ISO-8859-x (8-bit), not UTF8
442         as in the SIP protocol spec 
443         If doreserved == 1 we will convert reserved characters also.
444         RFC 2396, section 2.4
445         outbuf needs to have more memory allocated than the instring
446         to have room for the expansion. Every char that is converted
447         is replaced by three ASCII characters.
448
449         Note: The doreserved option is needed for replaces header in
450         SIP transfers.
451 */
452 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved) 
453 {
454         char *reserved = ";/?:@&=+$, "; /* Reserved chars */
455
456         const char *ptr  = string;      /* Start with the string */
457         char *out = NULL;
458         char *buf = NULL;
459
460         ast_copy_string(outbuf, string, buflen);
461
462         /* If there's no characters to convert, just go through and don't do anything */
463         while (*ptr) {
464                 if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
465                         /* Oops, we need to start working here */
466                         if (!buf) {
467                                 buf = outbuf;
468                                 out = buf + (ptr - string) ;    /* Set output ptr */
469                         }
470                         out += sprintf(out, "%%%02x", (unsigned char) *ptr);
471                 } else if (buf) {
472                         *out = *ptr;    /* Continue copying the string */
473                         out++;
474                 } 
475                 ptr++;
476         }
477         if (buf)
478                 *out = '\0';
479         return outbuf;
480 }
481
482 /*! \brief  ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)  */
483 void ast_uri_decode(char *s) 
484 {
485         char *o;
486         unsigned int tmp;
487
488         for (o = s; *s; s++, o++) {
489                 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
490                         /* have '%', two chars and correct parsing */
491                         *o = tmp;
492                         s += 2; /* Will be incremented once more when we break out */
493                 } else /* all other cases, just copy */
494                         *o = *s;
495         }
496         *o = '\0';
497 }
498
499 /*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
500 const char *ast_inet_ntoa(struct in_addr ia)
501 {
502         char *buf;
503
504         if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
505                 return "";
506
507         return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
508 }
509
510 #ifdef HAVE_DEV_URANDOM
511 static int dev_urandom_fd;
512 #endif
513
514 #ifndef __linux__
515 #undef pthread_create /* For ast_pthread_create function only */
516 #endif /* !__linux__ */
517
518 #if !defined(LOW_MEMORY)
519
520 #ifdef DEBUG_THREADS
521
522 /*! \brief A reasonable maximum number of locks a thread would be holding ... */
523 #define AST_MAX_LOCKS 16
524
525 /* Allow direct use of pthread_mutex_t and friends */
526 #undef pthread_mutex_t
527 #undef pthread_mutex_lock
528 #undef pthread_mutex_unlock
529 #undef pthread_mutex_init
530 #undef pthread_mutex_destroy
531
532 /*! 
533  * \brief Keep track of which locks a thread holds 
534  *
535  * There is an instance of this struct for every active thread
536  */
537 struct thr_lock_info {
538         /*! The thread's ID */
539         pthread_t thread_id;
540         /*! The thread name which includes where the thread was started */
541         const char *thread_name;
542         /*! This is the actual container of info for what locks this thread holds */
543         struct {
544                 const char *file;
545                 int line_num;
546                 const char *func;
547                 const char *lock_name;
548                 void *lock_addr;
549                 int times_locked;
550                 enum ast_lock_type type;
551                 /*! This thread is waiting on this lock */
552                 int pending:2;
553         } locks[AST_MAX_LOCKS];
554         /*! This is the number of locks currently held by this thread.
555          *  The index (num_locks - 1) has the info on the last one in the
556          *  locks member */
557         unsigned int num_locks;
558         /*! Protects the contents of the locks member 
559          * Intentionally not ast_mutex_t */
560         pthread_mutex_t lock;
561         AST_LIST_ENTRY(thr_lock_info) entry;
562 };
563
564 /*! 
565  * \brief Locked when accessing the lock_infos list 
566  */
567 AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
568 /*!
569  * \brief A list of each thread's lock info 
570  */
571 static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
572
573 /*!
574  * \brief Destroy a thread's lock info
575  *
576  * This gets called automatically when the thread stops
577  */
578 static void lock_info_destroy(void *data)
579 {
580         struct thr_lock_info *lock_info = data;
581
582         pthread_mutex_lock(&lock_infos_lock.mutex);
583         AST_LIST_REMOVE(&lock_infos, lock_info, entry);
584         pthread_mutex_unlock(&lock_infos_lock.mutex);
585
586         pthread_mutex_destroy(&lock_info->lock);
587         if (lock_info->thread_name)
588                 free((void *) lock_info->thread_name);
589         free(lock_info);
590 }
591
592 /*!
593  * \brief The thread storage key for per-thread lock info
594  */
595 AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
596
597 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
598         int line_num, const char *func, const char *lock_name, void *lock_addr)
599 {
600         struct thr_lock_info *lock_info;
601         int i;
602
603         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
604                 return;
605
606         pthread_mutex_lock(&lock_info->lock);
607
608         for (i = 0; i < lock_info->num_locks; i++) {
609                 if (lock_info->locks[i].lock_addr == lock_addr) {
610                         lock_info->locks[i].times_locked++;
611                         pthread_mutex_unlock(&lock_info->lock);
612                         return;
613                 }
614         }
615
616         if (lock_info->num_locks == AST_MAX_LOCKS) {
617                 /* Can't use ast_log here, because it will cause infinite recursion */
618                 fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
619                         "  Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
620                 pthread_mutex_unlock(&lock_info->lock);
621                 return;
622         }
623         
624         lock_info->locks[i].file = filename;
625         lock_info->locks[i].line_num = line_num;
626         lock_info->locks[i].func = func;
627         lock_info->locks[i].lock_name = lock_name;
628         lock_info->locks[i].lock_addr = lock_addr;
629         lock_info->locks[i].times_locked = 1;
630         lock_info->locks[i].type = type;
631         lock_info->locks[i].pending = 1;
632         lock_info->num_locks++;
633
634         pthread_mutex_unlock(&lock_info->lock);
635 }
636
637 void ast_mark_lock_acquired(void)
638 {
639         struct thr_lock_info *lock_info;
640
641         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
642                 return;
643
644         pthread_mutex_lock(&lock_info->lock);
645         lock_info->locks[lock_info->num_locks - 1].pending = 0;
646         pthread_mutex_unlock(&lock_info->lock);
647 }
648
649 void ast_mark_lock_failed(void)
650 {
651         struct thr_lock_info *lock_info;
652
653         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
654                 return;
655
656         pthread_mutex_lock(&lock_info->lock);
657         lock_info->locks[lock_info->num_locks - 1].pending = -1;
658         lock_info->locks[lock_info->num_locks - 1].times_locked--;
659         pthread_mutex_unlock(&lock_info->lock);
660 }
661
662 void ast_remove_lock_info(void *lock_addr)
663 {
664         struct thr_lock_info *lock_info;
665         int i = 0;
666
667         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
668                 return;
669
670         pthread_mutex_lock(&lock_info->lock);
671
672         for (i = lock_info->num_locks - 1; i >= 0; i--) {
673                 if (lock_info->locks[i].lock_addr == lock_addr)
674                         break;
675         }
676
677         if (i == -1) {
678                 /* Lock not found :( */
679                 pthread_mutex_unlock(&lock_info->lock);
680                 return;
681         }
682
683         if (lock_info->locks[i].times_locked > 1) {
684                 lock_info->locks[i].times_locked--;
685                 pthread_mutex_unlock(&lock_info->lock);
686                 return;
687         }
688
689         if (i < lock_info->num_locks - 1) {
690                 /* Not the last one ... *should* be rare! */
691                 memmove(&lock_info->locks[i], &lock_info->locks[i + 1], 
692                         (lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
693         }
694
695         lock_info->num_locks--;
696
697         pthread_mutex_unlock(&lock_info->lock);
698 }
699
700 static const char *locktype2str(enum ast_lock_type type)
701 {
702         switch (type) {
703         case AST_MUTEX:
704                 return "MUTEX";
705         case AST_RDLOCK:
706                 return "RDLOCK";
707         case AST_WRLOCK:
708                 return "WRLOCK";
709         }
710
711         return "UNKNOWN";
712 }
713
714 static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
715 {
716         struct thr_lock_info *lock_info;
717         struct ast_str *str;
718
719         if (!(str = ast_str_create(4096)))
720                 return CLI_FAILURE;
721
722         switch (cmd) {
723         case CLI_INIT:
724                 e->command = "core show locks";
725                 e->usage =
726                         "Usage: core show locks\n"
727                         "       This command is for lock debugging.  It prints out which locks\n"
728                         "are owned by each active thread.\n";
729                 return NULL;
730
731         case CLI_GENERATE:
732                 return NULL;
733         }
734
735         ast_str_append(&str, 0, "\n" 
736                        "=======================================================================\n"
737                        "=== Currently Held Locks ==============================================\n"
738                        "=======================================================================\n"
739                        "===\n"
740                        "=== <file> <line num> <function> <lock name> <lock addr> (times locked)\n"
741                        "===\n");
742
743         if (!str)
744                 return CLI_FAILURE;
745
746         pthread_mutex_lock(&lock_infos_lock.mutex);
747         AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
748                 int i;
749                 ast_str_append(&str, 0, "=== Thread ID: %d (%s)\n", (int) lock_info->thread_id,
750                         lock_info->thread_name);
751                 pthread_mutex_lock(&lock_info->lock);
752                 for (i = 0; str && i < lock_info->num_locks; i++) {
753                         int j;
754                         ast_mutex_t *lock;
755
756                         ast_str_append(&str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n", 
757                                 lock_info->locks[i].pending > 0 ? "Waiting for " : 
758                                         lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
759                                 lock_info->locks[i].file, 
760                                 locktype2str(lock_info->locks[i].type),
761                                 lock_info->locks[i].line_num,
762                                 lock_info->locks[i].func, lock_info->locks[i].lock_name,
763                                 lock_info->locks[i].lock_addr, 
764                                 lock_info->locks[i].times_locked);
765
766                         if (!lock_info->locks[i].pending)
767                                 continue;
768
769                         lock = lock_info->locks[i].lock_addr;
770
771                         ast_reentrancy_lock(lock);
772                         for (j = 0; str && j < lock->reentrancy; j++) {
773                                 ast_str_append(&str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
774                                         lock->file[j], lock->lineno[j], lock->func[j]);
775                         }
776                         ast_reentrancy_unlock(lock);    
777                 }
778                 pthread_mutex_unlock(&lock_info->lock);
779                 if (!str)
780                         break;
781                 ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
782                                "===\n");
783                 if (!str)
784                         break;
785         }
786         pthread_mutex_unlock(&lock_infos_lock.mutex);
787
788         if (!str)
789                 return CLI_FAILURE;
790
791         ast_str_append(&str, 0, "=======================================================================\n"
792                        "\n");
793
794         if (!str)
795                 return CLI_FAILURE;
796
797         ast_cli(a->fd, "%s", str->str);
798
799         free(str);
800
801         return CLI_SUCCESS;
802 }
803
804 static struct ast_cli_entry utils_cli[] = {
805         AST_CLI_DEFINE(handle_show_locks, "Show which locks are held by which thread"),
806 };
807
808 #endif /* DEBUG_THREADS */
809
810 /*
811  * support for 'show threads'. The start routine is wrapped by
812  * dummy_start(), so that ast_register_thread() and
813  * ast_unregister_thread() know the thread identifier.
814  */
815 struct thr_arg {
816         void *(*start_routine)(void *);
817         void *data;
818         char *name;
819 };
820
821 /*
822  * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
823  * are odd macros which start and end a block, so they _must_ be
824  * used in pairs (the latter with a '1' argument to call the
825  * handler on exit.
826  * On BSD we don't need this, but we keep it for compatibility.
827  */
828 static void *dummy_start(void *data)
829 {
830         void *ret;
831         struct thr_arg a = *((struct thr_arg *) data);  /* make a local copy */
832 #ifdef DEBUG_THREADS
833         struct thr_lock_info *lock_info;
834 #endif
835
836         /* note that even though data->name is a pointer to allocated memory,
837            we are not freeing it here because ast_register_thread is going to
838            keep a copy of the pointer and then ast_unregister_thread will
839            free the memory
840         */
841         ast_free(data);
842         ast_register_thread(a.name);
843         pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
844
845 #ifdef DEBUG_THREADS
846         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
847                 return NULL;
848
849         lock_info->thread_id = pthread_self();
850         lock_info->thread_name = strdup(a.name);
851         pthread_mutex_init(&lock_info->lock, NULL);
852
853         pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
854         AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
855         pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
856 #endif /* DEBUG_THREADS */
857
858         ret = a.start_routine(a.data);
859
860         pthread_cleanup_pop(1);
861
862         return ret;
863 }
864
865 #endif /* !LOW_MEMORY */
866
867 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
868                              void *data, size_t stacksize, const char *file, const char *caller,
869                              int line, const char *start_fn)
870 {
871 #if !defined(LOW_MEMORY)
872         struct thr_arg *a;
873 #endif
874
875         if (!attr) {
876                 attr = alloca(sizeof(*attr));
877                 pthread_attr_init(attr);
878         }
879
880 #ifdef __linux__
881         /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
882            which is kind of useless. Change this here to
883            PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
884            priority will propagate down to new threads by default.
885            This does mean that callers cannot set a different priority using
886            PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
887            the priority afterwards with pthread_setschedparam(). */
888         if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
889                 ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
890 #endif
891
892         if (!stacksize)
893                 stacksize = AST_STACKSIZE;
894
895         if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
896                 ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
897
898 #if !defined(LOW_MEMORY)
899         if ((a = ast_malloc(sizeof(*a)))) {
900                 a->start_routine = start_routine;
901                 a->data = data;
902                 start_routine = dummy_start;
903                 asprintf(&a->name, "%-20s started at [%5d] %s %s()",
904                          start_fn, line, file, caller);
905                 data = a;
906         }
907 #endif /* !LOW_MEMORY */
908
909         return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
910 }
911
912
913 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
914                              void *data, size_t stacksize, const char *file, const char *caller,
915                              int line, const char *start_fn)
916 {
917         unsigned char attr_destroy = 0;
918         int res;
919
920         if (!attr) {
921                 attr = alloca(sizeof(*attr));
922                 pthread_attr_init(attr);
923                 attr_destroy = 1;
924         }
925
926         if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
927                 ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
928
929         res = ast_pthread_create_stack(thread, attr, start_routine, data, 
930                                        stacksize, file, caller, line, start_fn);
931
932         if (attr_destroy)
933                 pthread_attr_destroy(attr);
934
935         return res;
936 }
937
938 int ast_wait_for_input(int fd, int ms)
939 {
940         struct pollfd pfd[1];
941         memset(pfd, 0, sizeof(pfd));
942         pfd[0].fd = fd;
943         pfd[0].events = POLLIN|POLLPRI;
944         return poll(pfd, 1, ms);
945 }
946
947 /*!
948  * Try to write string, but wait no more than ms milliseconds before timing out.
949  *
950  * \note The code assumes that the file descriptor has NONBLOCK set,
951  * so there is only one system call made to do a write, unless we actually
952  * have a need to wait.  This way, we get better performance.
953  * If the descriptor is blocking, all assumptions on the guaranteed
954  * detail do not apply anymore.
955  * Also note that in the current implementation, the delay is per-write,
956  * so you still have no guarantees, anyways.
957  * Fortunately the routine is only used in a few places (cli.c, manager.c,
958  * res_agi.c) so it is reasonably easy to check how it behaves there.
959  *
960  * XXX We either need to fix the code, or fix the documentation.
961  */
962 int ast_carefulwrite(int fd, char *s, int len, int timeoutms) 
963 {
964         /* Try to write string, but wait no more than ms milliseconds
965            before timing out */
966         int res = 0;
967         struct pollfd fds[1];
968         while (len) {
969                 res = write(fd, s, len);
970                 if ((res < 0) && (errno != EAGAIN)) {
971                         return -1;
972                 }
973                 if (res < 0)
974                         res = 0;
975                 len -= res;
976                 s += res;
977                 res = 0;
978                 if (len) {
979                         fds[0].fd = fd;
980                         fds[0].events = POLLOUT;
981                         /* Wait until writable again */
982                         res = poll(fds, 1, timeoutms);
983                         if (res < 1)
984                                 return -1;
985                 }
986         }
987         return res;
988 }
989
990 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
991 {
992         char *e;
993         char *q;
994
995         s = ast_strip(s);
996         if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
997                 e = s + strlen(s) - 1;
998                 if (*e == *(end_quotes + (q - beg_quotes))) {
999                         s++;
1000                         *e = '\0';
1001                 }
1002         }
1003
1004         return s;
1005 }
1006
1007 char *ast_unescape_semicolon(char *s)
1008 {
1009         char *e;
1010         char *work = s;
1011
1012         while ((e = strchr(work, ';'))) {
1013                 if ((e > work) && (*(e-1) == '\\')) {
1014                         memmove(e - 1, e, strlen(e) + 1);
1015                         work = e;
1016                 } else {
1017                         work = e + 1;
1018                 }
1019         }
1020
1021         return s;
1022 }
1023
1024 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
1025 {
1026         int result;
1027
1028         if (!buffer || !*buffer || !space || !*space)
1029                 return -1;
1030
1031         result = vsnprintf(*buffer, *space, fmt, ap);
1032
1033         if (result < 0)
1034                 return -1;
1035         else if (result > *space)
1036                 result = *space;
1037
1038         *buffer += result;
1039         *space -= result;
1040         return 0;
1041 }
1042
1043 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
1044 {
1045         va_list ap;
1046         int result;
1047
1048         va_start(ap, fmt);
1049         result = ast_build_string_va(buffer, space, fmt, ap);
1050         va_end(ap);
1051
1052         return result;
1053 }
1054
1055 int ast_true(const char *s)
1056 {
1057         if (ast_strlen_zero(s))
1058                 return 0;
1059
1060         /* Determine if this is a true value */
1061         if (!strcasecmp(s, "yes") ||
1062             !strcasecmp(s, "true") ||
1063             !strcasecmp(s, "y") ||
1064             !strcasecmp(s, "t") ||
1065             !strcasecmp(s, "1") ||
1066             !strcasecmp(s, "on"))
1067                 return -1;
1068
1069         return 0;
1070 }
1071
1072 int ast_false(const char *s)
1073 {
1074         if (ast_strlen_zero(s))
1075                 return 0;
1076
1077         /* Determine if this is a false value */
1078         if (!strcasecmp(s, "no") ||
1079             !strcasecmp(s, "false") ||
1080             !strcasecmp(s, "n") ||
1081             !strcasecmp(s, "f") ||
1082             !strcasecmp(s, "0") ||
1083             !strcasecmp(s, "off"))
1084                 return -1;
1085
1086         return 0;
1087 }
1088
1089 #define ONE_MILLION     1000000
1090 /*
1091  * put timeval in a valid range. usec is 0..999999
1092  * negative values are not allowed and truncated.
1093  */
1094 static struct timeval tvfix(struct timeval a)
1095 {
1096         if (a.tv_usec >= ONE_MILLION) {
1097                 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
1098                         a.tv_sec, (long int) a.tv_usec);
1099                 a.tv_sec += a.tv_usec / ONE_MILLION;
1100                 a.tv_usec %= ONE_MILLION;
1101         } else if (a.tv_usec < 0) {
1102                 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
1103                         a.tv_sec, (long int) a.tv_usec);
1104                 a.tv_usec = 0;
1105         }
1106         return a;
1107 }
1108
1109 struct timeval ast_tvadd(struct timeval a, struct timeval b)
1110 {
1111         /* consistency checks to guarantee usec in 0..999999 */
1112         a = tvfix(a);
1113         b = tvfix(b);
1114         a.tv_sec += b.tv_sec;
1115         a.tv_usec += b.tv_usec;
1116         if (a.tv_usec >= ONE_MILLION) {
1117                 a.tv_sec++;
1118                 a.tv_usec -= ONE_MILLION;
1119         }
1120         return a;
1121 }
1122
1123 struct timeval ast_tvsub(struct timeval a, struct timeval b)
1124 {
1125         /* consistency checks to guarantee usec in 0..999999 */
1126         a = tvfix(a);
1127         b = tvfix(b);
1128         a.tv_sec -= b.tv_sec;
1129         a.tv_usec -= b.tv_usec;
1130         if (a.tv_usec < 0) {
1131                 a.tv_sec-- ;
1132                 a.tv_usec += ONE_MILLION;
1133         }
1134         return a;
1135 }
1136 #undef ONE_MILLION
1137
1138 /*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
1139  * BSD libc (and others) do not. */
1140
1141 #ifndef linux
1142 AST_MUTEX_DEFINE_STATIC(randomlock);
1143 #endif
1144
1145 long int ast_random(void)
1146 {
1147         long int res;
1148 #ifdef HAVE_DEV_URANDOM
1149         if (dev_urandom_fd >= 0) {
1150                 int read_res = read(dev_urandom_fd, &res, sizeof(res));
1151                 if (read_res > 0)
1152                         return labs(res);
1153         }
1154 #endif
1155 #ifdef linux
1156         res = random();
1157 #else
1158         ast_mutex_lock(&randomlock);
1159         res = random();
1160         ast_mutex_unlock(&randomlock);
1161 #endif
1162         return res;
1163 }
1164
1165 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
1166 {
1167         char *dataPut = start;
1168         int inEscape = 0;
1169         int inQuotes = 0;
1170
1171         for (; *start; start++) {
1172                 if (inEscape) {
1173                         *dataPut++ = *start;       /* Always goes verbatim */
1174                         inEscape = 0;
1175                 } else {
1176                         if (*start == '\\') {
1177                                 inEscape = 1;      /* Do not copy \ into the data */
1178                         } else if (*start == '\'') {
1179                                 inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
1180                         } else {
1181                                 /* Replace , with |, unless in quotes */
1182                                 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1183                         }
1184                 }
1185         }
1186         if (start != dataPut)
1187                 *dataPut = 0;
1188         return dataPut;
1189 }
1190
1191 void ast_join(char *s, size_t len, char * const w[])
1192 {
1193         int x, ofs = 0;
1194         const char *src;
1195
1196         /* Join words into a string */
1197         if (!s)
1198                 return;
1199         for (x = 0; ofs < len && w[x]; x++) {
1200                 if (x > 0)
1201                         s[ofs++] = ' ';
1202                 for (src = w[x]; *src && ofs < len; src++)
1203                         s[ofs++] = *src;
1204         }
1205         if (ofs == len)
1206                 ofs--;
1207         s[ofs] = '\0';
1208 }
1209
1210 /*
1211  * stringfields support routines.
1212  */
1213
1214 const char __ast_string_field_empty[] = ""; /*!< the empty string */
1215
1216 /*! \brief add a new block to the pool.
1217  * We can only allocate from the topmost pool, so the
1218  * fields in *mgr reflect the size of that only.
1219  */
1220 static int add_string_pool(struct ast_string_field_mgr *mgr,
1221         struct ast_string_field_pool **pool_head, size_t size)
1222 {
1223         struct ast_string_field_pool *pool;
1224
1225         if (!(pool = ast_calloc(1, sizeof(*pool) + size)))
1226                 return -1;
1227         
1228         pool->prev = *pool_head;
1229         *pool_head = pool;
1230         mgr->size = size;
1231         mgr->used = 0;
1232
1233         return 0;
1234 }
1235
1236 /*
1237  * This is an internal API, code should not use it directly.
1238  * It initializes all fields as empty, then uses 'size' for 3 functions:
1239  * size > 0 means initialize the pool list with a pool of given size.
1240  *      This must be called right after allocating the object.
1241  * size = 0 means release all pools except the most recent one.
1242  *      This is useful to e.g. reset an object to the initial value.
1243  * size < 0 means release all pools.
1244  *      This must be done before destroying the object.
1245  */
1246 int __ast_string_field_init(struct ast_string_field_mgr *mgr,
1247         struct ast_string_field_pool **pool_head, size_t size)
1248 {
1249         const char **p = (const char **)pool_head + 1;
1250         struct ast_string_field_pool *cur = *pool_head;
1251
1252         /* clear fields - this is always necessary */
1253         while ((struct ast_string_field_mgr *)p != mgr)
1254                 *p++ = __ast_string_field_empty;
1255         if (size > 0) {                 /* allocate the initial pool */
1256                 *pool_head = NULL;
1257                 return add_string_pool(mgr, pool_head, size);
1258         }
1259         if (size < 0) {                 /* reset all pools */
1260                 *pool_head = NULL;
1261         } else {                        /* preserve the first pool */
1262                 if (cur == NULL) {
1263                         ast_log(LOG_WARNING, "trying to reset empty pool\n");
1264                         return -1;
1265                 }
1266                 cur = cur->prev;
1267                 (*pool_head)->prev = NULL;
1268                 mgr->used = 0;
1269         }
1270         while (cur) {
1271                 struct ast_string_field_pool *prev = cur->prev;
1272                 ast_free(cur);
1273                 cur = prev;
1274         }
1275         return 0;
1276 }
1277
1278 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
1279         struct ast_string_field_pool **pool_head, size_t needed)
1280 {
1281         char *result = NULL;
1282         size_t space = mgr->size - mgr->used;
1283
1284         if (__builtin_expect(needed > space, 0)) {
1285                 size_t new_size = mgr->size * 2;
1286
1287                 while (new_size < needed)
1288                         new_size *= 2;
1289
1290                 if (add_string_pool(mgr, pool_head, new_size))
1291                         return NULL;
1292         }
1293
1294         result = (*pool_head)->base + mgr->used;
1295         mgr->used += needed;
1296         return result;
1297 }
1298
1299 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
1300         struct ast_string_field_pool **pool_head,
1301         const ast_string_field *ptr, const char *format, va_list ap1, va_list ap2)
1302 {
1303         size_t needed;
1304         char *dst = (*pool_head)->base + mgr->used;
1305         const char **p = (const char **)ptr;
1306         size_t space = mgr->size - mgr->used;
1307
1308         /* try to write using available space */
1309         needed = vsnprintf(dst, space, format, ap1) + 1;
1310
1311         va_end(ap1);
1312
1313         if (needed > space) {   /* if it fails, reallocate */
1314                 size_t new_size = mgr->size * 2;
1315
1316                 while (new_size < needed)
1317                         new_size *= 2;
1318
1319                 if (add_string_pool(mgr, pool_head, new_size))
1320                         return;
1321
1322                 dst = (*pool_head)->base + mgr->used;
1323                 vsprintf(dst, format, ap2);
1324         }
1325
1326         *p = dst;
1327         mgr->used += needed;
1328 }
1329
1330 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
1331         struct ast_string_field_pool **pool_head,
1332         const ast_string_field *ptr, const char *format, ...)
1333 {
1334         va_list ap1, ap2;
1335
1336         va_start(ap1, format);
1337         va_start(ap2, format);          /* va_copy does not exist on FreeBSD */
1338
1339         __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
1340
1341         va_end(ap1);
1342         va_end(ap2);
1343 }
1344 /* end of stringfields support */
1345
1346 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
1347
1348 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
1349 {
1350         int ret;
1351         ast_mutex_lock(&fetchadd_m);
1352         ret = *p;
1353         *p += v;
1354         ast_mutex_unlock(&fetchadd_m);
1355         return ret;
1356 }
1357
1358 /*! \brief
1359  * get values from config variables.
1360  */
1361 int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
1362 {
1363         long double dtv = 0.0;
1364         int scanned;
1365
1366         if (dst == NULL)
1367                 return -1;
1368
1369         *dst = _default;
1370
1371         if (ast_strlen_zero(src))
1372                 return -1;
1373
1374         /* only integer at the moment, but one day we could accept more formats */
1375         if (sscanf(src, "%Lf%n", &dtv, &scanned) > 0) {
1376                 dst->tv_sec = dtv;
1377                 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
1378                 if (consumed)
1379                         *consumed = scanned;
1380                 return 0;
1381         } else
1382                 return -1;
1383 }
1384
1385 /*! \brief
1386  * get values from config variables.
1387  */
1388 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
1389 {
1390         long t;
1391         int scanned;
1392
1393         if (dst == NULL)
1394                 return -1;
1395
1396         *dst = _default;
1397
1398         if (ast_strlen_zero(src))
1399                 return -1;
1400
1401         /* only integer at the moment, but one day we could accept more formats */
1402         if (sscanf(src, "%ld%n", &t, &scanned) == 1) {
1403                 *dst = t;
1404                 if (consumed)
1405                         *consumed = scanned;
1406                 return 0;
1407         } else
1408                 return -1;
1409 }
1410
1411 /*!
1412  * core handler for dynamic strings.
1413  * This is not meant to be called directly, but rather through the
1414  * various wrapper macros
1415  *      ast_str_set(...)
1416  *      ast_str_append(...)
1417  *      ast_str_set_va(...)
1418  *      ast_str_append_va(...)
1419  */
1420 int __ast_str_helper(struct ast_str **buf, size_t max_len,
1421         int append, const char *fmt, va_list ap)
1422 {
1423         int res, need;
1424         int offset = (append && (*buf)->len) ? (*buf)->used : 0;
1425
1426         if (max_len < 0)
1427                 max_len = (*buf)->len;  /* don't exceed the allocated space */
1428         /*
1429          * Ask vsnprintf how much space we need. Remember that vsnprintf
1430          * does not count the final '\0' so we must add 1.
1431          */
1432         res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap);
1433
1434         need = res + offset + 1;
1435         /*
1436          * If there is not enough space and we are below the max length,
1437          * reallocate the buffer and return a message telling to retry.
1438          */
1439         if (need > (*buf)->len && (max_len == 0 || (*buf)->len < max_len) ) {
1440                 if (max_len && max_len < need)  /* truncate as needed */
1441                         need = max_len;
1442                 else if (max_len == 0)  /* if unbounded, give more room for next time */
1443                         need += 16 + need/4;
1444                 if (0)  /* debugging */
1445                         ast_verbose("extend from %d to %d\n", (int)(*buf)->len, need);
1446                 if (ast_str_make_space(buf, need)) {
1447                         ast_verbose("failed to extend from %d to %d\n", (int)(*buf)->len, need);
1448                         return AST_DYNSTR_BUILD_FAILED;
1449                 }
1450                 (*buf)->str[offset] = '\0';     /* Truncate the partial write. */
1451
1452                 /* va_end() and va_start() must be done before calling
1453                  * vsnprintf() again. */
1454                 return AST_DYNSTR_BUILD_RETRY;
1455         }
1456         /* update space used, keep in mind the truncation */
1457         (*buf)->used = (res + offset > (*buf)->len) ? (*buf)->len : res + offset;
1458
1459         return res;
1460 }
1461
1462 void ast_enable_packet_fragmentation(int sock)
1463 {
1464 #if defined(HAVE_IP_MTU_DISCOVER)
1465         int val = IP_PMTUDISC_DONT;
1466         
1467         if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
1468                 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
1469 #endif /* HAVE_IP_MTU_DISCOVER */
1470 }
1471
1472 int ast_mkdir(const char *path, int mode)
1473 {
1474         char *ptr;
1475         int len = strlen(path), count = 0, x, piececount = 0;
1476         char *tmp = ast_strdupa(path);
1477         char **pieces;
1478         char *fullpath = alloca(len + 1);
1479         int res = 0;
1480
1481         for (ptr = tmp; *ptr; ptr++) {
1482                 if (*ptr == '/')
1483                         count++;
1484         }
1485
1486         /* Count the components to the directory path */
1487         pieces = alloca(count * sizeof(*pieces));
1488         for (ptr = tmp; *ptr; ptr++) {
1489                 if (*ptr == '/') {
1490                         *ptr = '\0';
1491                         pieces[piececount++] = ptr + 1;
1492                 }
1493         }
1494
1495         *fullpath = '\0';
1496         for (x = 0; x < piececount; x++) {
1497                 /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
1498                 strcat(fullpath, "/");
1499                 strcat(fullpath, pieces[x]);
1500                 res = mkdir(fullpath, mode);
1501                 if (res && errno != EEXIST)
1502                         return errno;
1503         }
1504         return 0;
1505 }
1506
1507 int ast_utils_init(void)
1508 {
1509 #ifdef HAVE_DEV_URANDOM
1510         dev_urandom_fd = open("/dev/urandom", O_RDONLY);
1511 #endif
1512         base64_init();
1513 #ifdef DEBUG_THREADS
1514         ast_cli_register_multiple(utils_cli, sizeof(utils_cli) / sizeof(utils_cli[0]));
1515 #endif
1516         return 0;
1517 }