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