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