git migration: Refactor the ASTERISK_FILE_VERSION macro
[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 /*** MODULEINFO
27         <support_level>core</support_level>
28  ***/
29
30 #include "asterisk.h"
31
32 ASTERISK_REGISTER_FILE()
33
34 #include <ctype.h>
35 #include <fcntl.h>
36 #include <sys/stat.h>
37 #include <sys/syscall.h>
38 #include <unistd.h>
39 #if defined(__APPLE__)
40 #include <mach/mach.h>
41 #elif defined(HAVE_SYS_THR_H)
42 #include <sys/thr.h>
43 #endif
44
45 #include "asterisk/network.h"
46 #include "asterisk/ast_version.h"
47
48 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in lock.h if required */
49 #include "asterisk/lock.h"
50 #include "asterisk/io.h"
51 #include "asterisk/md5.h"
52 #include "asterisk/sha1.h"
53 #include "asterisk/cli.h"
54 #include "asterisk/linkedlists.h"
55 #include "asterisk/astobj2.h"
56
57 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
58 #include "asterisk/strings.h"
59
60 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
61 #include "asterisk/time.h"
62
63 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
64 #include "asterisk/stringfields.h"
65
66 #define AST_API_MODULE          /* ensure that inlinable API functions will be built in this module if required */
67 #include "asterisk/utils.h"
68
69 #define AST_API_MODULE
70 #include "asterisk/threadstorage.h"
71
72 #define AST_API_MODULE
73 #include "asterisk/config.h"
74
75 static char base64[64];
76 static char b2a[256];
77
78 AST_THREADSTORAGE(inet_ntoa_buf);
79
80 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
81
82 #define ERANGE 34       /*!< duh? ERANGE value copied from web... */
83 #undef gethostbyname
84
85 AST_MUTEX_DEFINE_STATIC(__mutex);
86
87 /*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
88 \note This
89 routine is derived from code originally written and placed in the public
90 domain by Enzo Michelangeli <em@em.no-ip.com> */
91
92 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
93                                 size_t buflen, struct hostent **result,
94                                 int *h_errnop)
95 {
96         int hsave;
97         struct hostent *ph;
98         ast_mutex_lock(&__mutex); /* begin critical area */
99         hsave = h_errno;
100
101         ph = gethostbyname(name);
102         *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
103         if (ph == NULL) {
104                 *result = NULL;
105         } else {
106                 char **p, **q;
107                 char *pbuf;
108                 int nbytes = 0;
109                 int naddr = 0, naliases = 0;
110                 /* determine if we have enough space in buf */
111
112                 /* count how many addresses */
113                 for (p = ph->h_addr_list; *p != 0; p++) {
114                         nbytes += ph->h_length; /* addresses */
115                         nbytes += sizeof(*p); /* pointers */
116                         naddr++;
117                 }
118                 nbytes += sizeof(*p); /* one more for the terminating NULL */
119
120                 /* count how many aliases, and total length of strings */
121                 for (p = ph->h_aliases; *p != 0; p++) {
122                         nbytes += (strlen(*p)+1); /* aliases */
123                         nbytes += sizeof(*p);  /* pointers */
124                         naliases++;
125                 }
126                 nbytes += sizeof(*p); /* one more for the terminating NULL */
127
128                 /* here nbytes is the number of bytes required in buffer */
129                 /* as a terminator must be there, the minimum value is ph->h_length */
130                 if (nbytes > buflen) {
131                         *result = NULL;
132                         ast_mutex_unlock(&__mutex); /* end critical area */
133                         return ERANGE; /* not enough space in buf!! */
134                 }
135
136                 /* There is enough space. Now we need to do a deep copy! */
137                 /* Allocation in buffer:
138                         from [0] to [(naddr-1) * sizeof(*p)]:
139                         pointers to addresses
140                         at [naddr * sizeof(*p)]:
141                         NULL
142                         from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
143                         pointers to aliases
144                         at [(naddr+naliases+1) * sizeof(*p)]:
145                         NULL
146                         then naddr addresses (fixed length), and naliases aliases (asciiz).
147                 */
148
149                 *ret = *ph;   /* copy whole structure (not its address!) */
150
151                 /* copy addresses */
152                 q = (char **)buf; /* pointer to pointers area (type: char **) */
153                 ret->h_addr_list = q; /* update pointer to address list */
154                 pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
155                 for (p = ph->h_addr_list; *p != 0; p++) {
156                         memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
157                         *q++ = pbuf; /* the pointer is the one inside buf... */
158                         pbuf += ph->h_length; /* advance pbuf */
159                 }
160                 *q++ = NULL; /* address list terminator */
161
162                 /* copy aliases */
163                 ret->h_aliases = q; /* update pointer to aliases list */
164                 for (p = ph->h_aliases; *p != 0; p++) {
165                         strcpy(pbuf, *p); /* copy alias strings */
166                         *q++ = pbuf; /* the pointer is the one inside buf... */
167                         pbuf += strlen(*p); /* advance pbuf */
168                         *pbuf++ = 0; /* string terminator */
169                 }
170                 *q++ = NULL; /* terminator */
171
172                 strcpy(pbuf, ph->h_name); /* copy alias strings */
173                 ret->h_name = pbuf;
174                 pbuf += strlen(ph->h_name); /* advance pbuf */
175                 *pbuf++ = 0; /* string terminator */
176
177                 *result = ret;  /* and let *result point to structure */
178
179         }
180         h_errno = hsave;  /* restore h_errno */
181         ast_mutex_unlock(&__mutex); /* end critical area */
182
183         return (*result == NULL); /* return 0 on success, non-zero on error */
184 }
185
186
187 #endif
188
189 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the
190    standard gethostbyname (which is not thread safe)
191 */
192 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
193 {
194         int res;
195         int herrno;
196         int dots = 0;
197         const char *s;
198         struct hostent *result = NULL;
199         /* Although it is perfectly legitimate to lookup a pure integer, for
200            the sake of the sanity of people who like to name their peers as
201            integers, we break with tradition and refuse to look up a
202            pure integer */
203         s = host;
204         res = 0;
205         while (s && *s) {
206                 if (*s == '.')
207                         dots++;
208                 else if (!isdigit(*s))
209                         break;
210                 s++;
211         }
212         if (!s || !*s) {
213                 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
214                 if (dots != 3)
215                         return NULL;
216                 memset(hp, 0, sizeof(struct ast_hostent));
217                 hp->hp.h_addrtype = AF_INET;
218                 hp->hp.h_addr_list = (void *) hp->buf;
219                 hp->hp.h_addr = hp->buf + sizeof(void *);
220                 /* For AF_INET, this will always be 4 */
221                 hp->hp.h_length = 4;
222                 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
223                         return &hp->hp;
224                 return NULL;
225
226         }
227 #ifdef HAVE_GETHOSTBYNAME_R_5
228         result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
229
230         if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
231                 return NULL;
232 #else
233         res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
234
235         if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
236                 return NULL;
237 #endif
238         return &hp->hp;
239 }
240
241 /*! \brief Produce 32 char MD5 hash of value. */
242 void ast_md5_hash(char *output, const char *input)
243 {
244         struct MD5Context md5;
245         unsigned char digest[16];
246         char *ptr;
247         int x;
248
249         MD5Init(&md5);
250         MD5Update(&md5, (const unsigned char *) input, strlen(input));
251         MD5Final(digest, &md5);
252         ptr = output;
253         for (x = 0; x < 16; x++)
254                 ptr += sprintf(ptr, "%02hhx", digest[x]);
255 }
256
257 /*! \brief Produce 40 char SHA1 hash of value. */
258 void ast_sha1_hash(char *output, const char *input)
259 {
260         struct SHA1Context sha;
261         char *ptr;
262         int x;
263         uint8_t Message_Digest[20];
264
265         SHA1Reset(&sha);
266
267         SHA1Input(&sha, (const unsigned char *) input, strlen(input));
268
269         SHA1Result(&sha, Message_Digest);
270         ptr = output;
271         for (x = 0; x < 20; x++)
272                 ptr += sprintf(ptr, "%02hhx", Message_Digest[x]);
273 }
274
275 /*! \brief Produce a 20 byte SHA1 hash of value. */
276 void ast_sha1_hash_uint(uint8_t *digest, const char *input)
277 {
278         struct SHA1Context sha;
279
280         SHA1Reset(&sha);
281
282         SHA1Input(&sha, (const unsigned char *) input, strlen(input));
283
284         SHA1Result(&sha, digest);
285 }
286
287 /*! \brief decode BASE64 encoded text */
288 int ast_base64decode(unsigned char *dst, const char *src, int max)
289 {
290         int cnt = 0;
291         unsigned int byte = 0;
292         unsigned int bits = 0;
293         int incnt = 0;
294         while(*src && *src != '=' && (cnt < max)) {
295                 /* Shift in 6 bits of input */
296                 byte <<= 6;
297                 byte |= (b2a[(int)(*src)]) & 0x3f;
298                 bits += 6;
299                 src++;
300                 incnt++;
301                 /* If we have at least 8 bits left over, take that character
302                    off the top */
303                 if (bits >= 8)  {
304                         bits -= 8;
305                         *dst = (byte >> bits) & 0xff;
306                         dst++;
307                         cnt++;
308                 }
309         }
310         /* Don't worry about left over bits, they're extra anyway */
311         return cnt;
312 }
313
314 /*! \brief encode text to BASE64 coding */
315 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
316 {
317         int cnt = 0;
318         int col = 0;
319         unsigned int byte = 0;
320         int bits = 0;
321         int cntin = 0;
322         /* Reserve space for null byte at end of string */
323         max--;
324         while ((cntin < srclen) && (cnt < max)) {
325                 byte <<= 8;
326                 byte |= *(src++);
327                 bits += 8;
328                 cntin++;
329                 if ((bits == 24) && (cnt + 4 <= max)) {
330                         *dst++ = base64[(byte >> 18) & 0x3f];
331                         *dst++ = base64[(byte >> 12) & 0x3f];
332                         *dst++ = base64[(byte >> 6) & 0x3f];
333                         *dst++ = base64[byte & 0x3f];
334                         cnt += 4;
335                         col += 4;
336                         bits = 0;
337                         byte = 0;
338                 }
339                 if (linebreaks && (cnt < max) && (col == 64)) {
340                         *dst++ = '\n';
341                         cnt++;
342                         col = 0;
343                 }
344         }
345         if (bits && (cnt + 4 <= max)) {
346                 /* Add one last character for the remaining bits,
347                    padding the rest with 0 */
348                 byte <<= 24 - bits;
349                 *dst++ = base64[(byte >> 18) & 0x3f];
350                 *dst++ = base64[(byte >> 12) & 0x3f];
351                 if (bits == 16)
352                         *dst++ = base64[(byte >> 6) & 0x3f];
353                 else
354                         *dst++ = '=';
355                 *dst++ = '=';
356                 cnt += 4;
357         }
358         if (linebreaks && (cnt < max)) {
359                 *dst++ = '\n';
360                 cnt++;
361         }
362         *dst = '\0';
363         return cnt;
364 }
365
366 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
367 {
368         return ast_base64encode_full(dst, src, srclen, max, 0);
369 }
370
371 static void base64_init(void)
372 {
373         int x;
374         memset(b2a, -1, sizeof(b2a));
375         /* Initialize base-64 Conversion table */
376         for (x = 0; x < 26; x++) {
377                 /* A-Z */
378                 base64[x] = 'A' + x;
379                 b2a['A' + x] = x;
380                 /* a-z */
381                 base64[x + 26] = 'a' + x;
382                 b2a['a' + x] = x + 26;
383                 /* 0-9 */
384                 if (x < 10) {
385                         base64[x + 52] = '0' + x;
386                         b2a['0' + x] = x + 52;
387                 }
388         }
389         base64[62] = '+';
390         base64[63] = '/';
391         b2a[(int)'+'] = 62;
392         b2a[(int)'/'] = 63;
393 }
394
395 const struct ast_flags ast_uri_http = {AST_URI_UNRESERVED};
396 const struct ast_flags ast_uri_http_legacy = {AST_URI_LEGACY_SPACE | AST_URI_UNRESERVED};
397 const struct ast_flags ast_uri_sip_user = {AST_URI_UNRESERVED | AST_URI_SIP_USER_UNRESERVED};
398
399 char *ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
400 {
401         const char *ptr  = string;      /* Start with the string */
402         char *out = outbuf;
403         const char *mark = "-_.!~*'()"; /* no encode set, RFC 2396 section 2.3, RFC 3261 sec 25 */
404         const char *user_unreserved = "&=+$,;?/"; /* user-unreserved set, RFC 3261 sec 25 */
405
406         while (*ptr && out - outbuf < buflen - 1) {
407                 if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *ptr == ' ') {
408                         /* for legacy encoding, encode spaces as '+' */
409                         *out = '+';
410                         out++;
411                 } else if (!(ast_test_flag(&spec, AST_URI_MARK)
412                                 && strchr(mark, *ptr))
413                         && !(ast_test_flag(&spec, AST_URI_ALPHANUM)
414                                 && ((*ptr >= '0' && *ptr <= '9')
415                                 || (*ptr >= 'A' && *ptr <= 'Z')
416                                 || (*ptr >= 'a' && *ptr <= 'z')))
417                         && !(ast_test_flag(&spec, AST_URI_SIP_USER_UNRESERVED)
418                                 && strchr(user_unreserved, *ptr))) {
419
420                         if (out - outbuf >= buflen - 3) {
421                                 break;
422                         }
423                         out += sprintf(out, "%%%02hhX", (unsigned char) *ptr);
424                 } else {
425                         *out = *ptr;    /* Continue copying the string */
426                         out++;
427                 }
428                 ptr++;
429         }
430
431         if (buflen) {
432                 *out = '\0';
433         }
434
435         return outbuf;
436 }
437
438 void ast_uri_decode(char *s, struct ast_flags spec)
439 {
440         char *o;
441         unsigned int tmp;
442
443         for (o = s; *s; s++, o++) {
444                 if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *s == '+') {
445                         /* legacy mode, decode '+' as space */
446                         *o = ' ';
447                 } else if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) {
448                         /* have '%', two chars and correct parsing */
449                         *o = tmp;
450                         s += 2; /* Will be incremented once more when we break out */
451                 } else /* all other cases, just copy */
452                         *o = *s;
453         }
454         *o = '\0';
455 }
456
457 char *ast_escape_quoted(const char *string, char *outbuf, int buflen)
458 {
459         const char *ptr  = string;
460         char *out = outbuf;
461         char *allow = "\t\v !"; /* allow LWS (minus \r and \n) and "!" */
462
463         while (*ptr && out - outbuf < buflen - 1) {
464                 if (!(strchr(allow, *ptr))
465                         && !(*ptr >= '#' && *ptr <= '[') /* %x23 - %x5b */
466                         && !(*ptr >= ']' && *ptr <= '~') /* %x5d - %x7e */
467                         && !((unsigned char) *ptr > 0x7f)) {             /* UTF8-nonascii */
468
469                         if (out - outbuf >= buflen - 2) {
470                                 break;
471                         }
472                         out += sprintf(out, "\\%c", (unsigned char) *ptr);
473                 } else {
474                         *out = *ptr;
475                         out++;
476                 }
477                 ptr++;
478         }
479
480         if (buflen) {
481                 *out = '\0';
482         }
483
484         return outbuf;
485 }
486
487 char *ast_escape_semicolons(const char *string, char *outbuf, int buflen)
488 {
489         const char *ptr = string;
490         char *out = outbuf;
491
492         if (string == NULL || outbuf == NULL) {
493                 ast_assert(string != NULL && outbuf != NULL);
494                 return NULL;
495         }
496
497         while (*ptr && out - outbuf < buflen - 1) {
498                 if (*ptr == ';') {
499                         if (out - outbuf >= buflen - 2) {
500                                 break;
501                         }
502                         strcpy(out, "\\;");
503                         out += 2;
504                 } else {
505                         *out = *ptr;
506                         out++;
507                 }
508                 ptr++;
509         }
510
511         if (buflen) {
512                 *out = '\0';
513         }
514
515         return outbuf;
516 }
517
518 void ast_unescape_quoted(char *quote_str)
519 {
520         int esc_pos;
521         int unesc_pos;
522         int quote_str_len = strlen(quote_str);
523
524         for (esc_pos = 0, unesc_pos = 0;
525                 esc_pos < quote_str_len;
526                 esc_pos++, unesc_pos++) {
527                 if (quote_str[esc_pos] == '\\') {
528                         /* at least one more char and current is \\ */
529                         esc_pos++;
530                         if (esc_pos >= quote_str_len) {
531                                 break;
532                         }
533                 }
534
535                 quote_str[unesc_pos] = quote_str[esc_pos];
536         }
537         quote_str[unesc_pos] = '\0';
538 }
539
540 int ast_xml_escape(const char *string, char * const outbuf, const size_t buflen)
541 {
542         char *dst = outbuf;
543         char *end = outbuf + buflen - 1; /* save one for the null terminator */
544
545         /* Handle the case for the empty output buffer */
546         if (buflen == 0) {
547                 return -1;
548         }
549
550         /* Escaping rules from http://www.w3.org/TR/REC-xml/#syntax */
551         /* This also prevents partial entities at the end of a string */
552         while (*string && dst < end) {
553                 const char *entity = NULL;
554                 int len = 0;
555
556                 switch (*string) {
557                 case '<':
558                         entity = "&lt;";
559                         len = 4;
560                         break;
561                 case '&':
562                         entity = "&amp;";
563                         len = 5;
564                         break;
565                 case '>':
566                         /* necessary if ]]> is in the string; easier to escape them all */
567                         entity = "&gt;";
568                         len = 4;
569                         break;
570                 case '\'':
571                         /* necessary in single-quoted strings; easier to escape them all */
572                         entity = "&apos;";
573                         len = 6;
574                         break;
575                 case '"':
576                         /* necessary in double-quoted strings; easier to escape them all */
577                         entity = "&quot;";
578                         len = 6;
579                         break;
580                 default:
581                         *dst++ = *string++;
582                         break;
583                 }
584
585                 if (entity) {
586                         ast_assert(len == strlen(entity));
587                         if (end - dst < len) {
588                                 /* no room for the entity; stop */
589                                 break;
590                         }
591                         /* just checked for length; strcpy is fine */
592                         strcpy(dst, entity);
593                         dst += len;
594                         ++string;
595                 }
596         }
597         /* Write null terminator */
598         *dst = '\0';
599         /* If any chars are left in string, return failure */
600         return *string == '\0' ? 0 : -1;
601 }
602
603 /*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
604 const char *ast_inet_ntoa(struct in_addr ia)
605 {
606         char *buf;
607
608         if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
609                 return "";
610
611         return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
612 }
613
614 static int dev_urandom_fd = -1;
615
616 #ifndef __linux__
617 #undef pthread_create /* For ast_pthread_create function only */
618 #endif /* !__linux__ */
619
620 #if !defined(LOW_MEMORY)
621
622 #ifdef DEBUG_THREADS
623
624 /*! \brief A reasonable maximum number of locks a thread would be holding ... */
625 #define AST_MAX_LOCKS 64
626
627 /* Allow direct use of pthread_mutex_t and friends */
628 #undef pthread_mutex_t
629 #undef pthread_mutex_lock
630 #undef pthread_mutex_unlock
631 #undef pthread_mutex_init
632 #undef pthread_mutex_destroy
633
634 /*!
635  * \brief Keep track of which locks a thread holds
636  *
637  * There is an instance of this struct for every active thread
638  */
639 struct thr_lock_info {
640         /*! The thread's ID */
641         pthread_t thread_id;
642         /*! The thread name which includes where the thread was started */
643         const char *thread_name;
644         /*! This is the actual container of info for what locks this thread holds */
645         struct {
646                 const char *file;
647                 const char *func;
648                 const char *lock_name;
649                 void *lock_addr;
650                 int times_locked;
651                 int line_num;
652                 enum ast_lock_type type;
653                 /*! This thread is waiting on this lock */
654                 int pending:2;
655                 /*! A condition has suspended this lock */
656                 int suspended:1;
657 #ifdef HAVE_BKTR
658                 struct ast_bt *backtrace;
659 #endif
660         } locks[AST_MAX_LOCKS];
661         /*! This is the number of locks currently held by this thread.
662          *  The index (num_locks - 1) has the info on the last one in the
663          *  locks member */
664         unsigned int num_locks;
665         /*! The LWP id (which GDB prints) */
666         int lwp;
667         /*! Protects the contents of the locks member
668          * Intentionally not ast_mutex_t */
669         pthread_mutex_t lock;
670         AST_LIST_ENTRY(thr_lock_info) entry;
671 };
672
673 /*!
674  * \brief Locked when accessing the lock_infos list
675  */
676 AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
677 /*!
678  * \brief A list of each thread's lock info
679  */
680 static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
681
682 /*!
683  * \brief Destroy a thread's lock info
684  *
685  * This gets called automatically when the thread stops
686  */
687 static void lock_info_destroy(void *data)
688 {
689         struct thr_lock_info *lock_info = data;
690         int i;
691
692         pthread_mutex_lock(&lock_infos_lock.mutex);
693         AST_LIST_REMOVE(&lock_infos, lock_info, entry);
694         pthread_mutex_unlock(&lock_infos_lock.mutex);
695
696
697         for (i = 0; i < lock_info->num_locks; i++) {
698                 if (lock_info->locks[i].pending == -1) {
699                         /* This just means that the last lock this thread went for was by
700                          * using trylock, and it failed.  This is fine. */
701                         break;
702                 }
703
704                 ast_log(LOG_ERROR,
705                         "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n",
706                         lock_info->thread_name,
707                         lock_info->locks[i].lock_name,
708                         lock_info->locks[i].lock_addr,
709                         lock_info->locks[i].func,
710                         lock_info->locks[i].file,
711                         lock_info->locks[i].line_num
712                 );
713         }
714
715         pthread_mutex_destroy(&lock_info->lock);
716         if (lock_info->thread_name) {
717                 ast_free((void *) lock_info->thread_name);
718         }
719         ast_free(lock_info);
720 }
721
722 /*!
723  * \brief The thread storage key for per-thread lock info
724  */
725 AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
726 #ifdef HAVE_BKTR
727 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
728         int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
729 #else
730 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
731         int line_num, const char *func, const char *lock_name, void *lock_addr)
732 #endif
733 {
734         struct thr_lock_info *lock_info;
735         int i;
736
737         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
738                 return;
739
740         pthread_mutex_lock(&lock_info->lock);
741
742         for (i = 0; i < lock_info->num_locks; i++) {
743                 if (lock_info->locks[i].lock_addr == lock_addr) {
744                         lock_info->locks[i].times_locked++;
745 #ifdef HAVE_BKTR
746                         lock_info->locks[i].backtrace = bt;
747 #endif
748                         pthread_mutex_unlock(&lock_info->lock);
749                         return;
750                 }
751         }
752
753         if (lock_info->num_locks == AST_MAX_LOCKS) {
754                 /* Can't use ast_log here, because it will cause infinite recursion */
755                 fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
756                         "  Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
757                 pthread_mutex_unlock(&lock_info->lock);
758                 return;
759         }
760
761         if (i && lock_info->locks[i - 1].pending == -1) {
762                 /* The last lock on the list was one that this thread tried to lock but
763                  * failed at doing so.  It has now moved on to something else, so remove
764                  * the old lock from the list. */
765                 i--;
766                 lock_info->num_locks--;
767                 memset(&lock_info->locks[i], 0, sizeof(lock_info->locks[0]));
768         }
769
770         lock_info->locks[i].file = filename;
771         lock_info->locks[i].line_num = line_num;
772         lock_info->locks[i].func = func;
773         lock_info->locks[i].lock_name = lock_name;
774         lock_info->locks[i].lock_addr = lock_addr;
775         lock_info->locks[i].times_locked = 1;
776         lock_info->locks[i].type = type;
777         lock_info->locks[i].pending = 1;
778 #ifdef HAVE_BKTR
779         lock_info->locks[i].backtrace = bt;
780 #endif
781         lock_info->num_locks++;
782
783         pthread_mutex_unlock(&lock_info->lock);
784 }
785
786 void ast_mark_lock_acquired(void *lock_addr)
787 {
788         struct thr_lock_info *lock_info;
789
790         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
791                 return;
792
793         pthread_mutex_lock(&lock_info->lock);
794         if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
795                 lock_info->locks[lock_info->num_locks - 1].pending = 0;
796         }
797         pthread_mutex_unlock(&lock_info->lock);
798 }
799
800 void ast_mark_lock_failed(void *lock_addr)
801 {
802         struct thr_lock_info *lock_info;
803
804         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
805                 return;
806
807         pthread_mutex_lock(&lock_info->lock);
808         if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
809                 lock_info->locks[lock_info->num_locks - 1].pending = -1;
810                 lock_info->locks[lock_info->num_locks - 1].times_locked--;
811         }
812         pthread_mutex_unlock(&lock_info->lock);
813 }
814
815 int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, int *lineno, char *func, size_t func_size, char *mutex_name, size_t mutex_name_size)
816 {
817         struct thr_lock_info *lock_info;
818         int i = 0;
819
820         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
821                 return -1;
822
823         pthread_mutex_lock(&lock_info->lock);
824
825         for (i = lock_info->num_locks - 1; i >= 0; i--) {
826                 if (lock_info->locks[i].lock_addr == lock_addr)
827                         break;
828         }
829
830         if (i == -1) {
831                 /* Lock not found :( */
832                 pthread_mutex_unlock(&lock_info->lock);
833                 return -1;
834         }
835
836         ast_copy_string(filename, lock_info->locks[i].file, filename_size);
837         *lineno = lock_info->locks[i].line_num;
838         ast_copy_string(func, lock_info->locks[i].func, func_size);
839         ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
840
841         pthread_mutex_unlock(&lock_info->lock);
842
843         return 0;
844 }
845
846 void ast_suspend_lock_info(void *lock_addr)
847 {
848         struct thr_lock_info *lock_info;
849         int i = 0;
850
851         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info)))) {
852                 return;
853         }
854
855         pthread_mutex_lock(&lock_info->lock);
856
857         for (i = lock_info->num_locks - 1; i >= 0; i--) {
858                 if (lock_info->locks[i].lock_addr == lock_addr)
859                         break;
860         }
861
862         if (i == -1) {
863                 /* Lock not found :( */
864                 pthread_mutex_unlock(&lock_info->lock);
865                 return;
866         }
867
868         lock_info->locks[i].suspended = 1;
869
870         pthread_mutex_unlock(&lock_info->lock);
871 }
872
873 void ast_restore_lock_info(void *lock_addr)
874 {
875         struct thr_lock_info *lock_info;
876         int i = 0;
877
878         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
879                 return;
880
881         pthread_mutex_lock(&lock_info->lock);
882
883         for (i = lock_info->num_locks - 1; i >= 0; i--) {
884                 if (lock_info->locks[i].lock_addr == lock_addr)
885                         break;
886         }
887
888         if (i == -1) {
889                 /* Lock not found :( */
890                 pthread_mutex_unlock(&lock_info->lock);
891                 return;
892         }
893
894         lock_info->locks[i].suspended = 0;
895
896         pthread_mutex_unlock(&lock_info->lock);
897 }
898
899
900 #ifdef HAVE_BKTR
901 void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
902 #else
903 void ast_remove_lock_info(void *lock_addr)
904 #endif
905 {
906         struct thr_lock_info *lock_info;
907         int i = 0;
908
909         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
910                 return;
911
912         pthread_mutex_lock(&lock_info->lock);
913
914         for (i = lock_info->num_locks - 1; i >= 0; i--) {
915                 if (lock_info->locks[i].lock_addr == lock_addr)
916                         break;
917         }
918
919         if (i == -1) {
920                 /* Lock not found :( */
921                 pthread_mutex_unlock(&lock_info->lock);
922                 return;
923         }
924
925         if (lock_info->locks[i].times_locked > 1) {
926                 lock_info->locks[i].times_locked--;
927 #ifdef HAVE_BKTR
928                 lock_info->locks[i].backtrace = bt;
929 #endif
930                 pthread_mutex_unlock(&lock_info->lock);
931                 return;
932         }
933
934         if (i < lock_info->num_locks - 1) {
935                 /* Not the last one ... *should* be rare! */
936                 memmove(&lock_info->locks[i], &lock_info->locks[i + 1],
937                         (lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
938         }
939
940         lock_info->num_locks--;
941
942         pthread_mutex_unlock(&lock_info->lock);
943 }
944
945 static const char *locktype2str(enum ast_lock_type type)
946 {
947         switch (type) {
948         case AST_MUTEX:
949                 return "MUTEX";
950         case AST_RDLOCK:
951                 return "RDLOCK";
952         case AST_WRLOCK:
953                 return "WRLOCK";
954         }
955
956         return "UNKNOWN";
957 }
958
959 #ifdef HAVE_BKTR
960 static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
961 {
962         char **symbols;
963         int num_frames;
964
965         if (!bt) {
966                 ast_str_append(str, 0, "\tNo backtrace to print\n");
967                 return;
968         }
969
970         /* store frame count locally to avoid the memory corruption that
971          * sometimes happens on virtualized CentOS 6.x systems */
972         num_frames = bt->num_frames;
973         if ((symbols = ast_bt_get_symbols(bt->addresses, num_frames))) {
974                 int frame_iterator;
975
976                 for (frame_iterator = 0; frame_iterator < num_frames; ++frame_iterator) {
977                         ast_str_append(str, 0, "\t%s\n", symbols[frame_iterator]);
978                 }
979
980                 ast_std_free(symbols);
981         } else {
982                 ast_str_append(str, 0, "\tCouldn't retrieve backtrace symbols\n");
983         }
984 }
985 #endif
986
987 static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
988 {
989         int j;
990         ast_mutex_t *lock;
991         struct ast_lock_track *lt;
992
993         ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d%s)\n",
994                                    lock_info->locks[i].pending > 0 ? "Waiting for " :
995                                    lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
996                                    lock_info->locks[i].file,
997                                    locktype2str(lock_info->locks[i].type),
998                                    lock_info->locks[i].line_num,
999                                    lock_info->locks[i].func, lock_info->locks[i].lock_name,
1000                                    lock_info->locks[i].lock_addr,
1001                                    lock_info->locks[i].times_locked,
1002                                    lock_info->locks[i].suspended ? " - suspended" : "");
1003 #ifdef HAVE_BKTR
1004         append_backtrace_information(str, lock_info->locks[i].backtrace);
1005 #endif
1006
1007         if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
1008                 return;
1009
1010         /* We only have further details for mutexes right now */
1011         if (lock_info->locks[i].type != AST_MUTEX)
1012                 return;
1013
1014         lock = lock_info->locks[i].lock_addr;
1015         lt = lock->track;
1016         ast_reentrancy_lock(lt);
1017         for (j = 0; *str && j < lt->reentrancy; j++) {
1018                 ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
1019                                            lt->file[j], lt->lineno[j], lt->func[j]);
1020         }
1021         ast_reentrancy_unlock(lt);
1022 }
1023
1024
1025 /*! This function can help you find highly temporal locks; locks that happen for a
1026     short time, but at unexpected times, usually at times that create a deadlock,
1027         Why is this thing locked right then? Who is locking it? Who am I fighting
1028     with for this lock?
1029
1030         To answer such questions, just call this routine before you would normally try
1031         to aquire a lock. It doesn't do anything if the lock is not acquired. If the
1032         lock is taken, it will publish a line or two to the console via ast_log().
1033
1034         Sometimes, the lock message is pretty uninformative. For instance, you might
1035         find that the lock is being aquired deep within the astobj2 code; this tells
1036         you little about higher level routines that call the astobj2 routines.
1037         But, using gdb, you can set a break at the ast_log below, and for that
1038         breakpoint, you can set the commands:
1039           where
1040           cont
1041         which will give a stack trace and continue. -- that aught to do the job!
1042
1043 */
1044 void ast_log_show_lock(void *this_lock_addr)
1045 {
1046         struct thr_lock_info *lock_info;
1047         struct ast_str *str;
1048
1049         if (!(str = ast_str_create(4096))) {
1050                 ast_log(LOG_NOTICE,"Could not create str\n");
1051                 return;
1052         }
1053
1054
1055         pthread_mutex_lock(&lock_infos_lock.mutex);
1056         AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
1057                 int i;
1058                 pthread_mutex_lock(&lock_info->lock);
1059                 for (i = 0; str && i < lock_info->num_locks; i++) {
1060                         /* ONLY show info about this particular lock, if
1061                            it's acquired... */
1062                         if (lock_info->locks[i].lock_addr == this_lock_addr) {
1063                                 append_lock_information(&str, lock_info, i);
1064                                 ast_log(LOG_NOTICE, "%s", ast_str_buffer(str));
1065                                 break;
1066                         }
1067                 }
1068                 pthread_mutex_unlock(&lock_info->lock);
1069         }
1070         pthread_mutex_unlock(&lock_infos_lock.mutex);
1071         ast_free(str);
1072 }
1073
1074
1075 struct ast_str *ast_dump_locks(void)
1076 {
1077         struct thr_lock_info *lock_info;
1078         struct ast_str *str;
1079
1080         if (!(str = ast_str_create(4096))) {
1081                 return NULL;
1082         }
1083
1084         ast_str_append(&str, 0, "\n"
1085                        "=======================================================================\n"
1086                        "=== %s\n"
1087                        "=== Currently Held Locks\n"
1088                        "=======================================================================\n"
1089                        "===\n"
1090                        "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n"
1091                        "===\n", ast_get_version());
1092
1093         if (!str) {
1094                 return NULL;
1095         }
1096
1097         pthread_mutex_lock(&lock_infos_lock.mutex);
1098         AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
1099                 int i;
1100                 int header_printed = 0;
1101                 pthread_mutex_lock(&lock_info->lock);
1102                 for (i = 0; str && i < lock_info->num_locks; i++) {
1103                         /* Don't show suspended locks */
1104                         if (lock_info->locks[i].suspended) {
1105                                 continue;
1106                         }
1107
1108                         if (!header_printed) {
1109                                 if (lock_info->lwp != -1) {
1110                                         ast_str_append(&str, 0, "=== Thread ID: 0x%lx LWP:%d (%s)\n",
1111                                                 (long unsigned) lock_info->thread_id, lock_info->lwp, lock_info->thread_name);
1112                                 } else {
1113                                         ast_str_append(&str, 0, "=== Thread ID: 0x%lx (%s)\n",
1114                                                 (long unsigned) lock_info->thread_id, lock_info->thread_name);
1115                                 }
1116                                 header_printed = 1;
1117                         }
1118
1119                         append_lock_information(&str, lock_info, i);
1120                 }
1121                 pthread_mutex_unlock(&lock_info->lock);
1122                 if (!str) {
1123                         break;
1124                 }
1125                 if (header_printed) {
1126                         ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
1127                                 "===\n");
1128                 }
1129                 if (!str) {
1130                         break;
1131                 }
1132         }
1133         pthread_mutex_unlock(&lock_infos_lock.mutex);
1134
1135         if (!str) {
1136                 return NULL;
1137         }
1138
1139         ast_str_append(&str, 0, "=======================================================================\n"
1140                        "\n");
1141
1142         return str;
1143 }
1144
1145 static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1146 {
1147         struct ast_str *str;
1148
1149         switch (cmd) {
1150         case CLI_INIT:
1151                 e->command = "core show locks";
1152                 e->usage =
1153                         "Usage: core show locks\n"
1154                         "       This command is for lock debugging.  It prints out which locks\n"
1155                         "are owned by each active thread.\n";
1156                 return NULL;
1157
1158         case CLI_GENERATE:
1159                 return NULL;
1160         }
1161
1162         str = ast_dump_locks();
1163         if (!str) {
1164                 return CLI_FAILURE;
1165         }
1166
1167         ast_cli(a->fd, "%s", ast_str_buffer(str));
1168
1169         ast_free(str);
1170
1171         return CLI_SUCCESS;
1172 }
1173
1174 static struct ast_cli_entry utils_cli[] = {
1175         AST_CLI_DEFINE(handle_show_locks, "Show which locks are held by which thread"),
1176 };
1177
1178 #endif /* DEBUG_THREADS */
1179
1180 /*
1181  * support for 'show threads'. The start routine is wrapped by
1182  * dummy_start(), so that ast_register_thread() and
1183  * ast_unregister_thread() know the thread identifier.
1184  */
1185 struct thr_arg {
1186         void *(*start_routine)(void *);
1187         void *data;
1188         char *name;
1189 };
1190
1191 /*
1192  * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
1193  * are odd macros which start and end a block, so they _must_ be
1194  * used in pairs (the latter with a '1' argument to call the
1195  * handler on exit.
1196  * On BSD we don't need this, but we keep it for compatibility.
1197  */
1198 static void *dummy_start(void *data)
1199 {
1200         void *ret;
1201         struct thr_arg a = *((struct thr_arg *) data);  /* make a local copy */
1202 #ifdef DEBUG_THREADS
1203         struct thr_lock_info *lock_info;
1204         pthread_mutexattr_t mutex_attr;
1205
1206         if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
1207                 return NULL;
1208
1209         lock_info->thread_id = pthread_self();
1210         lock_info->lwp = ast_get_tid();
1211         lock_info->thread_name = strdup(a.name);
1212
1213         pthread_mutexattr_init(&mutex_attr);
1214         pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
1215         pthread_mutex_init(&lock_info->lock, &mutex_attr);
1216         pthread_mutexattr_destroy(&mutex_attr);
1217
1218         pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
1219         AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
1220         pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
1221 #endif /* DEBUG_THREADS */
1222
1223         /* note that even though data->name is a pointer to allocated memory,
1224            we are not freeing it here because ast_register_thread is going to
1225            keep a copy of the pointer and then ast_unregister_thread will
1226            free the memory
1227         */
1228         ast_free(data);
1229         ast_register_thread(a.name);
1230         pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
1231
1232         ret = a.start_routine(a.data);
1233
1234         pthread_cleanup_pop(1);
1235
1236         return ret;
1237 }
1238
1239 #endif /* !LOW_MEMORY */
1240
1241 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
1242                              void *data, size_t stacksize, const char *file, const char *caller,
1243                              int line, const char *start_fn)
1244 {
1245 #if !defined(LOW_MEMORY)
1246         struct thr_arg *a;
1247 #endif
1248
1249         if (!attr) {
1250                 attr = ast_alloca(sizeof(*attr));
1251                 pthread_attr_init(attr);
1252         }
1253
1254 #ifdef __linux__
1255         /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
1256            which is kind of useless. Change this here to
1257            PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
1258            priority will propagate down to new threads by default.
1259            This does mean that callers cannot set a different priority using
1260            PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
1261            the priority afterwards with pthread_setschedparam(). */
1262         if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
1263                 ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
1264 #endif
1265
1266         if (!stacksize)
1267                 stacksize = AST_STACKSIZE;
1268
1269         if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
1270                 ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
1271
1272 #if !defined(LOW_MEMORY)
1273         if ((a = ast_malloc(sizeof(*a)))) {
1274                 a->start_routine = start_routine;
1275                 a->data = data;
1276                 start_routine = dummy_start;
1277                 if (ast_asprintf(&a->name, "%-20s started at [%5d] %s %s()",
1278                              start_fn, line, file, caller) < 0) {
1279                         a->name = NULL;
1280                 }
1281                 data = a;
1282         }
1283 #endif /* !LOW_MEMORY */
1284
1285         return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
1286 }
1287
1288
1289 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
1290                              void *data, size_t stacksize, const char *file, const char *caller,
1291                              int line, const char *start_fn)
1292 {
1293         unsigned char attr_destroy = 0;
1294         int res;
1295
1296         if (!attr) {
1297                 attr = ast_alloca(sizeof(*attr));
1298                 pthread_attr_init(attr);
1299                 attr_destroy = 1;
1300         }
1301
1302         if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
1303                 ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
1304
1305         res = ast_pthread_create_stack(thread, attr, start_routine, data,
1306                                        stacksize, file, caller, line, start_fn);
1307
1308         if (attr_destroy)
1309                 pthread_attr_destroy(attr);
1310
1311         return res;
1312 }
1313
1314 int ast_wait_for_input(int fd, int ms)
1315 {
1316         struct pollfd pfd[1];
1317
1318         memset(pfd, 0, sizeof(pfd));
1319         pfd[0].fd = fd;
1320         pfd[0].events = POLLIN | POLLPRI;
1321         return ast_poll(pfd, 1, ms);
1322 }
1323
1324 int ast_wait_for_output(int fd, int ms)
1325 {
1326         struct pollfd pfd[1];
1327
1328         memset(pfd, 0, sizeof(pfd));
1329         pfd[0].fd = fd;
1330         pfd[0].events = POLLOUT;
1331         return ast_poll(pfd, 1, ms);
1332 }
1333
1334 static int wait_for_output(int fd, int timeoutms)
1335 {
1336         struct pollfd pfd = {
1337                 .fd = fd,
1338                 .events = POLLOUT,
1339         };
1340         int res;
1341         struct timeval start = ast_tvnow();
1342         int elapsed = 0;
1343
1344         /* poll() until the fd is writable without blocking */
1345         while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
1346                 if (res == 0) {
1347                         /* timed out. */
1348 #ifndef STANDALONE
1349                         ast_debug(1, "Timed out trying to write\n");
1350 #endif
1351                         return -1;
1352                 } else if (res == -1) {
1353                         /* poll() returned an error, check to see if it was fatal */
1354
1355                         if (errno == EINTR || errno == EAGAIN) {
1356                                 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1357                                 if (elapsed >= timeoutms) {
1358                                         return -1;
1359                                 }
1360                                 /* This was an acceptable error, go back into poll() */
1361                                 continue;
1362                         }
1363
1364                         /* Fatal error, bail. */
1365                         ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
1366
1367                         return -1;
1368                 }
1369                 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1370                 if (elapsed >= timeoutms) {
1371                         return -1;
1372                 }
1373         }
1374
1375         return 0;
1376 }
1377
1378 /*!
1379  * Try to write string, but wait no more than ms milliseconds before timing out.
1380  *
1381  * \note The code assumes that the file descriptor has NONBLOCK set,
1382  * so there is only one system call made to do a write, unless we actually
1383  * have a need to wait.  This way, we get better performance.
1384  * If the descriptor is blocking, all assumptions on the guaranteed
1385  * detail do not apply anymore.
1386  */
1387 int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
1388 {
1389         struct timeval start = ast_tvnow();
1390         int res = 0;
1391         int elapsed = 0;
1392
1393         while (len) {
1394                 if (wait_for_output(fd, timeoutms - elapsed)) {
1395                         return -1;
1396                 }
1397
1398                 res = write(fd, s, len);
1399
1400                 if (res < 0 && errno != EAGAIN && errno != EINTR) {
1401                         /* fatal error from write() */
1402                         ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
1403                         return -1;
1404                 }
1405
1406                 if (res < 0) {
1407                         /* It was an acceptable error */
1408                         res = 0;
1409                 }
1410
1411                 /* Update how much data we have left to write */
1412                 len -= res;
1413                 s += res;
1414                 res = 0;
1415
1416                 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1417                 if (elapsed >= timeoutms) {
1418                         /* We've taken too long to write
1419                          * This is only an error condition if we haven't finished writing. */
1420                         res = len ? -1 : 0;
1421                         break;
1422                 }
1423         }
1424
1425         return res;
1426 }
1427
1428 int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeoutms)
1429 {
1430         struct timeval start = ast_tvnow();
1431         int n = 0;
1432         int elapsed = 0;
1433
1434         while (len) {
1435                 if (wait_for_output(fd, timeoutms - elapsed)) {
1436                         /* poll returned a fatal error, so bail out immediately. */
1437                         return -1;
1438                 }
1439
1440                 /* Clear any errors from a previous write */
1441                 clearerr(f);
1442
1443                 n = fwrite(src, 1, len, f);
1444
1445                 if (ferror(f) && errno != EINTR && errno != EAGAIN) {
1446                         /* fatal error from fwrite() */
1447                         if (!feof(f)) {
1448                                 /* Don't spam the logs if it was just that the connection is closed. */
1449                                 ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno));
1450                         }
1451                         n = -1;
1452                         break;
1453                 }
1454
1455                 /* Update for data already written to the socket */
1456                 len -= n;
1457                 src += n;
1458
1459                 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1460                 if (elapsed >= timeoutms) {
1461                         /* We've taken too long to write
1462                          * This is only an error condition if we haven't finished writing. */
1463                         n = len ? -1 : 0;
1464                         break;
1465                 }
1466         }
1467
1468         errno = 0;
1469         while (fflush(f)) {
1470                 if (errno == EAGAIN || errno == EINTR) {
1471                         /* fflush() does not appear to reset errno if it flushes
1472                          * and reaches EOF at the same time. It returns EOF with
1473                          * the last seen value of errno, causing a possible loop.
1474                          * Also usleep() to reduce CPU eating if it does loop */
1475                         errno = 0;
1476                         usleep(1);
1477                         continue;
1478                 }
1479                 if (errno && !feof(f)) {
1480                         /* Don't spam the logs if it was just that the connection is closed. */
1481                         ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno));
1482                 }
1483                 n = -1;
1484                 break;
1485         }
1486
1487         return n < 0 ? -1 : 0;
1488 }
1489
1490 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
1491 {
1492         char *e;
1493         char *q;
1494
1495         s = ast_strip(s);
1496         if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
1497                 e = s + strlen(s) - 1;
1498                 if (*e == *(end_quotes + (q - beg_quotes))) {
1499                         s++;
1500                         *e = '\0';
1501                 }
1502         }
1503
1504         return s;
1505 }
1506
1507 char *ast_strsep(char **iss, const char sep, uint32_t flags)
1508 {
1509         char *st = *iss;
1510         char *is;
1511         int inquote = 0;
1512         int found = 0;
1513         char stack[8];
1514
1515         if (iss == NULL || *iss == '\0') {
1516                 return NULL;
1517         }
1518
1519         memset(stack, 0, sizeof(stack));
1520
1521         for(is = st; *is; is++) {
1522                 if (*is == '\\') {
1523                         if (*++is != '\0') {
1524                                 is++;
1525                         } else {
1526                                 break;
1527                         }
1528                 }
1529
1530                 if (*is == '\'' || *is == '"') {
1531                         if (*is == stack[inquote]) {
1532                                 stack[inquote--] = '\0';
1533                         } else {
1534                                 if (++inquote >= sizeof(stack)) {
1535                                         return NULL;
1536                                 }
1537                                 stack[inquote] = *is;
1538                         }
1539                 }
1540
1541                 if (*is == sep && !inquote) {
1542                         *is = '\0';
1543                         found = 1;
1544                         *iss = is + 1;
1545                         break;
1546                 }
1547         }
1548         if (!found) {
1549                 *iss = NULL;
1550         }
1551
1552         if (flags & AST_STRSEP_STRIP) {
1553                 st = ast_strip_quoted(st, "'\"", "'\"");
1554         }
1555
1556         if (flags & AST_STRSEP_TRIM) {
1557                 st = ast_strip(st);
1558         }
1559
1560         if (flags & AST_STRSEP_UNESCAPE) {
1561                 ast_unescape_quoted(st);
1562         }
1563
1564         return st;
1565 }
1566
1567 char *ast_unescape_semicolon(char *s)
1568 {
1569         char *e;
1570         char *work = s;
1571
1572         while ((e = strchr(work, ';'))) {
1573                 if ((e > work) && (*(e-1) == '\\')) {
1574                         memmove(e - 1, e, strlen(e) + 1);
1575                         work = e;
1576                 } else {
1577                         work = e + 1;
1578                 }
1579         }
1580
1581         return s;
1582 }
1583
1584 /* !\brief unescape some C sequences in place, return pointer to the original string.
1585  */
1586 char *ast_unescape_c(char *src)
1587 {
1588         char c, *ret, *dst;
1589
1590         if (src == NULL)
1591                 return NULL;
1592         for (ret = dst = src; (c = *src++); *dst++ = c ) {
1593                 if (c != '\\')
1594                         continue;       /* copy char at the end of the loop */
1595                 switch ((c = *src++)) {
1596                 case '\0':      /* special, trailing '\' */
1597                         c = '\\';
1598                         break;
1599                 case 'b':       /* backspace */
1600                         c = '\b';
1601                         break;
1602                 case 'f':       /* form feed */
1603                         c = '\f';
1604                         break;
1605                 case 'n':
1606                         c = '\n';
1607                         break;
1608                 case 'r':
1609                         c = '\r';
1610                         break;
1611                 case 't':
1612                         c = '\t';
1613                         break;
1614                 }
1615                 /* default, use the char literally */
1616         }
1617         *dst = '\0';
1618         return ret;
1619 }
1620
1621 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
1622 {
1623         int result;
1624
1625         if (!buffer || !*buffer || !space || !*space)
1626                 return -1;
1627
1628         result = vsnprintf(*buffer, *space, fmt, ap);
1629
1630         if (result < 0)
1631                 return -1;
1632         else if (result > *space)
1633                 result = *space;
1634
1635         *buffer += result;
1636         *space -= result;
1637         return 0;
1638 }
1639
1640 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
1641 {
1642         va_list ap;
1643         int result;
1644
1645         va_start(ap, fmt);
1646         result = ast_build_string_va(buffer, space, fmt, ap);
1647         va_end(ap);
1648
1649         return result;
1650 }
1651
1652 int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str **regex_pattern)
1653 {
1654         int regex_len = strlen(regex_string);
1655         int ret = 3;
1656
1657         /* Chop off the leading / if there is one */
1658         if ((regex_len >= 1) && (regex_string[0] == '/')) {
1659                 ast_str_set(regex_pattern, 0, "%s", regex_string + 1);
1660                 ret -= 2;
1661         }
1662
1663         /* Chop off the ending / if there is one */
1664         if ((regex_len > 1) && (regex_string[regex_len - 1] == '/')) {
1665                 ast_str_truncate(*regex_pattern, -1);
1666                 ret -= 1;
1667         }
1668
1669         return ret;
1670 }
1671
1672 int ast_true(const char *s)
1673 {
1674         if (ast_strlen_zero(s))
1675                 return 0;
1676
1677         /* Determine if this is a true value */
1678         if (!strcasecmp(s, "yes") ||
1679             !strcasecmp(s, "true") ||
1680             !strcasecmp(s, "y") ||
1681             !strcasecmp(s, "t") ||
1682             !strcasecmp(s, "1") ||
1683             !strcasecmp(s, "on"))
1684                 return -1;
1685
1686         return 0;
1687 }
1688
1689 int ast_false(const char *s)
1690 {
1691         if (ast_strlen_zero(s))
1692                 return 0;
1693
1694         /* Determine if this is a false value */
1695         if (!strcasecmp(s, "no") ||
1696             !strcasecmp(s, "false") ||
1697             !strcasecmp(s, "n") ||
1698             !strcasecmp(s, "f") ||
1699             !strcasecmp(s, "0") ||
1700             !strcasecmp(s, "off"))
1701                 return -1;
1702
1703         return 0;
1704 }
1705
1706 #define ONE_MILLION     1000000
1707 /*
1708  * put timeval in a valid range. usec is 0..999999
1709  * negative values are not allowed and truncated.
1710  */
1711 static struct timeval tvfix(struct timeval a)
1712 {
1713         if (a.tv_usec >= ONE_MILLION) {
1714                 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
1715                         (long)a.tv_sec, (long int) a.tv_usec);
1716                 a.tv_sec += a.tv_usec / ONE_MILLION;
1717                 a.tv_usec %= ONE_MILLION;
1718         } else if (a.tv_usec < 0) {
1719                 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
1720                         (long)a.tv_sec, (long int) a.tv_usec);
1721                 a.tv_usec = 0;
1722         }
1723         return a;
1724 }
1725
1726 struct timeval ast_tvadd(struct timeval a, struct timeval b)
1727 {
1728         /* consistency checks to guarantee usec in 0..999999 */
1729         a = tvfix(a);
1730         b = tvfix(b);
1731         a.tv_sec += b.tv_sec;
1732         a.tv_usec += b.tv_usec;
1733         if (a.tv_usec >= ONE_MILLION) {
1734                 a.tv_sec++;
1735                 a.tv_usec -= ONE_MILLION;
1736         }
1737         return a;
1738 }
1739
1740 struct timeval ast_tvsub(struct timeval a, struct timeval b)
1741 {
1742         /* consistency checks to guarantee usec in 0..999999 */
1743         a = tvfix(a);
1744         b = tvfix(b);
1745         a.tv_sec -= b.tv_sec;
1746         a.tv_usec -= b.tv_usec;
1747         if (a.tv_usec < 0) {
1748                 a.tv_sec-- ;
1749                 a.tv_usec += ONE_MILLION;
1750         }
1751         return a;
1752 }
1753
1754 int ast_remaining_ms(struct timeval start, int max_ms)
1755 {
1756         int ms;
1757
1758         if (max_ms < 0) {
1759                 ms = max_ms;
1760         } else {
1761                 ms = max_ms - ast_tvdiff_ms(ast_tvnow(), start);
1762                 if (ms < 0) {
1763                         ms = 0;
1764                 }
1765         }
1766
1767         return ms;
1768 }
1769
1770 void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length)
1771 {
1772         int durh, durm, durs;
1773         durh = duration / 3600;
1774         durm = (duration % 3600) / 60;
1775         durs = duration % 60;
1776         snprintf(buf, length, "%02d:%02d:%02d", durh, durm, durs);
1777 }
1778
1779 #undef ONE_MILLION
1780
1781 #ifndef linux
1782 AST_MUTEX_DEFINE_STATIC(randomlock);
1783 #endif
1784
1785 long int ast_random(void)
1786 {
1787         long int res;
1788
1789         if (dev_urandom_fd >= 0) {
1790                 int read_res = read(dev_urandom_fd, &res, sizeof(res));
1791                 if (read_res > 0) {
1792                         long int rm = RAND_MAX;
1793                         res = res < 0 ? ~res : res;
1794                         rm++;
1795                         return res % rm;
1796                 }
1797         }
1798
1799         /* XXX - Thread safety really depends on the libc, not the OS.
1800          *
1801          * But... popular Linux libc's (uClibc, glibc, eglibc), all have a
1802          * somewhat thread safe random(3) (results are random, but not
1803          * reproducible). The libc's for other systems (BSD, et al.), not so
1804          * much.
1805          */
1806 #ifdef linux
1807         res = random();
1808 #else
1809         ast_mutex_lock(&randomlock);
1810         res = random();
1811         ast_mutex_unlock(&randomlock);
1812 #endif
1813         return res;
1814 }
1815
1816 void ast_replace_subargument_delimiter(char *s)
1817 {
1818         for (; *s; s++) {
1819                 if (*s == '^') {
1820                         *s = ',';
1821                 }
1822         }
1823 }
1824
1825 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
1826 {
1827         char *dataPut = start;
1828         int inEscape = 0;
1829         int inQuotes = 0;
1830
1831         for (; *start; start++) {
1832                 if (inEscape) {
1833                         *dataPut++ = *start;       /* Always goes verbatim */
1834                         inEscape = 0;
1835                 } else {
1836                         if (*start == '\\') {
1837                                 inEscape = 1;      /* Do not copy \ into the data */
1838                         } else if (*start == '\'') {
1839                                 inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
1840                         } else {
1841                                 /* Replace , with |, unless in quotes */
1842                                 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1843                         }
1844                 }
1845         }
1846         if (start != dataPut)
1847                 *dataPut = 0;
1848         return dataPut;
1849 }
1850
1851 void ast_join_delim(char *s, size_t len, const char * const w[], unsigned int size, char delim)
1852 {
1853         int x, ofs = 0;
1854         const char *src;
1855
1856         /* Join words into a string */
1857         if (!s)
1858                 return;
1859         for (x = 0; ofs < len && x < size && w[x] ; x++) {
1860                 if (x > 0)
1861                         s[ofs++] = delim;
1862                 for (src = w[x]; *src && ofs < len; src++)
1863                         s[ofs++] = *src;
1864         }
1865         if (ofs == len)
1866                 ofs--;
1867         s[ofs] = '\0';
1868 }
1869
1870 char *ast_to_camel_case_delim(const char *s, const char *delim)
1871 {
1872         char *res = ast_strdup(s);
1873         char *front, *back, *buf = res;
1874         int size;
1875
1876         front = strtok_r(buf, delim, &back);
1877
1878         while (front) {
1879                 size = strlen(front);
1880                 *front = toupper(*front);
1881                 ast_copy_string(buf, front, size + 1);
1882                 buf += size;
1883                 front = strtok_r(NULL, delim, &back);
1884         }
1885
1886         return res;
1887 }
1888
1889 /*
1890  * stringfields support routines.
1891  */
1892
1893 /* this is a little complex... string fields are stored with their
1894    allocated size in the bytes preceding the string; even the
1895    constant 'empty' string has to be this way, so the code that
1896    checks to see if there is enough room for a new string doesn't
1897    have to have any special case checks
1898 */
1899
1900 static const struct {
1901         ast_string_field_allocation allocation;
1902         char string[1];
1903 } __ast_string_field_empty_buffer;
1904
1905 ast_string_field __ast_string_field_empty = __ast_string_field_empty_buffer.string;
1906
1907 #define ALLOCATOR_OVERHEAD 48
1908
1909 static size_t optimal_alloc_size(size_t size)
1910 {
1911         unsigned int count;
1912
1913         size += ALLOCATOR_OVERHEAD;
1914
1915         for (count = 1; size; size >>= 1, count++);
1916
1917         return (1 << count) - ALLOCATOR_OVERHEAD;
1918 }
1919
1920 /*! \brief add a new block to the pool.
1921  * We can only allocate from the topmost pool, so the
1922  * fields in *mgr reflect the size of that only.
1923  */
1924 static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
1925                            size_t size, const char *file, int lineno, const char *func)
1926 {
1927         struct ast_string_field_pool *pool;
1928         size_t alloc_size = optimal_alloc_size(sizeof(*pool) + size);
1929
1930 #if defined(__AST_DEBUG_MALLOC)
1931         if (!(pool = __ast_calloc(1, alloc_size, file, lineno, func))) {
1932                 return -1;
1933         }
1934 #else
1935         if (!(pool = ast_calloc(1, alloc_size))) {
1936                 return -1;
1937         }
1938 #endif
1939
1940         pool->prev = *pool_head;
1941         pool->size = alloc_size - sizeof(*pool);
1942         *pool_head = pool;
1943         mgr->last_alloc = NULL;
1944
1945         return 0;
1946 }
1947
1948 /*
1949  * This is an internal API, code should not use it directly.
1950  * It initializes all fields as empty, then uses 'size' for 3 functions:
1951  * size > 0 means initialize the pool list with a pool of given size.
1952  *      This must be called right after allocating the object.
1953  * size = 0 means release all pools except the most recent one.
1954  *      If the first pool was allocated via embedding in another
1955  *      object, that pool will be preserved instead.
1956  *      This is useful to e.g. reset an object to the initial value.
1957  * size < 0 means release all pools.
1958  *      This must be done before destroying the object.
1959  */
1960 int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
1961                             int needed, const char *file, int lineno, const char *func)
1962 {
1963         const char **p = (const char **) pool_head + 1;
1964         struct ast_string_field_pool *cur = NULL;
1965         struct ast_string_field_pool *preserve = NULL;
1966
1967         /* clear fields - this is always necessary */
1968         while ((struct ast_string_field_mgr *) p != mgr) {
1969                 *p++ = __ast_string_field_empty;
1970         }
1971
1972         mgr->last_alloc = NULL;
1973 #if defined(__AST_DEBUG_MALLOC)
1974         mgr->owner_file = file;
1975         mgr->owner_func = func;
1976         mgr->owner_line = lineno;
1977 #endif
1978         if (needed > 0) {               /* allocate the initial pool */
1979                 *pool_head = NULL;
1980                 mgr->embedded_pool = NULL;
1981                 return add_string_pool(mgr, pool_head, needed, file, lineno, func);
1982         }
1983
1984         /* if there is an embedded pool, we can't actually release *all*
1985          * pools, we must keep the embedded one. if the caller is about
1986          * to free the structure that contains the stringfield manager
1987          * and embedded pool anyway, it will be freed as part of that
1988          * operation.
1989          */
1990         if ((needed < 0) && mgr->embedded_pool) {
1991                 needed = 0;
1992         }
1993
1994         if (needed < 0) {               /* reset all pools */
1995                 cur = *pool_head;
1996         } else if (mgr->embedded_pool) { /* preserve the embedded pool */
1997                 preserve = mgr->embedded_pool;
1998                 cur = *pool_head;
1999         } else {                        /* preserve the last pool */
2000                 if (*pool_head == NULL) {
2001                         ast_log(LOG_WARNING, "trying to reset empty pool\n");
2002                         return -1;
2003                 }
2004                 preserve = *pool_head;
2005                 cur = preserve->prev;
2006         }
2007
2008         if (preserve) {
2009                 preserve->prev = NULL;
2010                 preserve->used = preserve->active = 0;
2011         }
2012
2013         while (cur) {
2014                 struct ast_string_field_pool *prev = cur->prev;
2015
2016                 if (cur != preserve) {
2017                         ast_free(cur);
2018                 }
2019                 cur = prev;
2020         }
2021
2022         *pool_head = preserve;
2023
2024         return 0;
2025 }
2026
2027 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
2028                                                 struct ast_string_field_pool **pool_head, size_t needed)
2029 {
2030         char *result = NULL;
2031         size_t space = (*pool_head)->size - (*pool_head)->used;
2032         size_t to_alloc;
2033
2034         /* Make room for ast_string_field_allocation and make it a multiple of that. */
2035         to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
2036         ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);
2037
2038         if (__builtin_expect(to_alloc > space, 0)) {
2039                 size_t new_size = (*pool_head)->size;
2040
2041                 while (new_size < to_alloc) {
2042                         new_size *= 2;
2043                 }
2044
2045 #if defined(__AST_DEBUG_MALLOC)
2046                 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
2047                         return NULL;
2048 #else
2049                 if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
2050                         return NULL;
2051 #endif
2052         }
2053
2054         /* pool->base is always aligned (gcc aligned attribute). We ensure that
2055          * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
2056          * causing result to always be aligned as well; which in turn fixes that
2057          * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
2058         result = (*pool_head)->base + (*pool_head)->used;
2059         (*pool_head)->used += to_alloc;
2060         (*pool_head)->active += needed;
2061         result += ast_alignof(ast_string_field_allocation);
2062         AST_STRING_FIELD_ALLOCATION(result) = needed;
2063         mgr->last_alloc = result;
2064
2065         return result;
2066 }
2067
2068 int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr,
2069                                 struct ast_string_field_pool **pool_head, size_t needed,
2070                                 const ast_string_field *ptr)
2071 {
2072         ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
2073         size_t space = (*pool_head)->size - (*pool_head)->used;
2074
2075         if (*ptr != mgr->last_alloc) {
2076                 return 1;
2077         }
2078
2079         if (space < grow) {
2080                 return 1;
2081         }
2082
2083         (*pool_head)->used += grow;
2084         (*pool_head)->active += grow;
2085         AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
2086
2087         return 0;
2088 }
2089
2090 void __ast_string_field_release_active(struct ast_string_field_pool *pool_head,
2091                                        const ast_string_field ptr)
2092 {
2093         struct ast_string_field_pool *pool, *prev;
2094
2095         if (ptr == __ast_string_field_empty) {
2096                 return;
2097         }
2098
2099         for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
2100                 if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
2101                         pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
2102                         if (pool->active == 0) {
2103                                 if (prev) {
2104                                         prev->prev = pool->prev;
2105                                         ast_free(pool);
2106                                 } else {
2107                                         pool->used = 0;
2108                                 }
2109                         }
2110                         break;
2111                 }
2112         }
2113 }
2114
2115 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
2116                                      struct ast_string_field_pool **pool_head,
2117                                      ast_string_field *ptr, const char *format, va_list ap)
2118 {
2119         size_t needed;
2120         size_t available;
2121         size_t space = (*pool_head)->size - (*pool_head)->used;
2122         int res;
2123         ssize_t grow;
2124         char *target;
2125         va_list ap2;
2126
2127         /* if the field already has space allocated, try to reuse it;
2128            otherwise, try to use the empty space at the end of the current
2129            pool
2130         */
2131         if (*ptr != __ast_string_field_empty) {
2132                 target = (char *) *ptr;
2133                 available = AST_STRING_FIELD_ALLOCATION(*ptr);
2134                 if (*ptr == mgr->last_alloc) {
2135                         available += space;
2136                 }
2137         } else {
2138                 /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
2139                  * so we don't need to re-align anything here.
2140                  */
2141                 target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
2142                 if (space > ast_alignof(ast_string_field_allocation)) {
2143                         available = space - ast_alignof(ast_string_field_allocation);
2144                 } else {
2145                         available = 0;
2146                 }
2147         }
2148
2149         va_copy(ap2, ap);
2150         res = vsnprintf(target, available, format, ap2);
2151         va_end(ap2);
2152
2153         if (res < 0) {
2154                 /* Are we out of memory? */
2155                 return;
2156         }
2157         if (res == 0) {
2158                 __ast_string_field_release_active(*pool_head, *ptr);
2159                 *ptr = __ast_string_field_empty;
2160                 return;
2161         }
2162         needed = (size_t)res + 1; /* NUL byte */
2163
2164         if (needed > available) {
2165                 /* the allocation could not be satisfied using the field's current allocation
2166                    (if it has one), or the space available in the pool (if it does not). allocate
2167                    space for it, adding a new string pool if necessary.
2168                 */
2169                 if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
2170                         return;
2171                 }
2172                 vsprintf(target, format, ap);
2173                 va_end(ap); /* XXX va_end without va_start? */
2174                 __ast_string_field_release_active(*pool_head, *ptr);
2175                 *ptr = target;
2176         } else if (*ptr != target) {
2177                 /* the allocation was satisfied using available space in the pool, but not
2178                    using the space already allocated to the field
2179                 */
2180                 __ast_string_field_release_active(*pool_head, *ptr);
2181                 mgr->last_alloc = *ptr = target;
2182                 ast_assert(needed < (ast_string_field_allocation)-1);
2183                 AST_STRING_FIELD_ALLOCATION(target) = (ast_string_field_allocation)needed;
2184                 (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
2185                 (*pool_head)->active += needed;
2186         } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
2187                 /* the allocation was satisfied by using available space in the pool *and*
2188                    the field was the last allocated field from the pool, so it grew
2189                 */
2190                 AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
2191                 (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
2192                 (*pool_head)->active += grow;
2193         }
2194 }
2195
2196 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
2197                                   struct ast_string_field_pool **pool_head,
2198                                   ast_string_field *ptr, const char *format, ...)
2199 {
2200         va_list ap;
2201
2202         va_start(ap, format);
2203         __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap);
2204         va_end(ap);
2205 }
2206
2207 void *__ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
2208                                      size_t field_mgr_pool_offset, size_t pool_size, const char *file,
2209                                      int lineno, const char *func)
2210 {
2211         struct ast_string_field_mgr *mgr;
2212         struct ast_string_field_pool *pool;
2213         struct ast_string_field_pool **pool_head;
2214         size_t pool_size_needed = sizeof(*pool) + pool_size;
2215         size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
2216         void *allocation;
2217         unsigned int x;
2218
2219 #if defined(__AST_DEBUG_MALLOC)
2220         if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
2221                 return NULL;
2222         }
2223 #else
2224         if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
2225                 return NULL;
2226         }
2227 #endif
2228
2229         for (x = 0; x < num_structs; x++) {
2230                 void *base = allocation + (size_to_alloc * x);
2231                 const char **p;
2232
2233                 mgr = base + field_mgr_offset;
2234                 pool_head = base + field_mgr_pool_offset;
2235                 pool = base + struct_size;
2236
2237                 p = (const char **) pool_head + 1;
2238                 while ((struct ast_string_field_mgr *) p != mgr) {
2239                         *p++ = __ast_string_field_empty;
2240                 }
2241
2242                 mgr->embedded_pool = pool;
2243                 *pool_head = pool;
2244                 pool->size = size_to_alloc - struct_size - sizeof(*pool);
2245 #if defined(__AST_DEBUG_MALLOC)
2246                 mgr->owner_file = file;
2247                 mgr->owner_func = func;
2248                 mgr->owner_line = lineno;
2249 #endif
2250         }
2251
2252         return allocation;
2253 }
2254
2255 /* end of stringfields support */
2256
2257 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
2258
2259 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
2260 {
2261         int ret;
2262         ast_mutex_lock(&fetchadd_m);
2263         ret = *p;
2264         *p += v;
2265         ast_mutex_unlock(&fetchadd_m);
2266         return ret;
2267 }
2268
2269 /*! \brief
2270  * get values from config variables.
2271  */
2272 int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
2273 {
2274         long double dtv = 0.0;
2275         int scanned;
2276
2277         if (dst == NULL)
2278                 return -1;
2279
2280         *dst = _default;
2281
2282         if (ast_strlen_zero(src))
2283                 return -1;
2284
2285         /* only integer at the moment, but one day we could accept more formats */
2286         if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
2287                 dst->tv_sec = dtv;
2288                 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
2289                 if (consumed)
2290                         *consumed = scanned;
2291                 return 0;
2292         } else
2293                 return -1;
2294 }
2295
2296 /*! \brief
2297  * get values from config variables.
2298  */
2299 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
2300 {
2301         long t;
2302         int scanned;
2303
2304         if (dst == NULL)
2305                 return -1;
2306
2307         *dst = _default;
2308
2309         if (ast_strlen_zero(src))
2310                 return -1;
2311
2312         /* only integer at the moment, but one day we could accept more formats */
2313         if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
2314                 *dst = t;
2315                 if (consumed)
2316                         *consumed = scanned;
2317                 return 0;
2318         } else
2319                 return -1;
2320 }
2321
2322 void ast_enable_packet_fragmentation(int sock)
2323 {
2324 #if defined(HAVE_IP_MTU_DISCOVER)
2325         int val = IP_PMTUDISC_DONT;
2326
2327         if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
2328                 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
2329 #endif /* HAVE_IP_MTU_DISCOVER */
2330 }
2331
2332 int ast_mkdir(const char *path, int mode)
2333 {
2334         char *ptr;
2335         int len = strlen(path), count = 0, x, piececount = 0;
2336         char *tmp = ast_strdupa(path);
2337         char **pieces;
2338         char *fullpath = ast_alloca(len + 1);
2339         int res = 0;
2340
2341         for (ptr = tmp; *ptr; ptr++) {
2342                 if (*ptr == '/')
2343                         count++;
2344         }
2345
2346         /* Count the components to the directory path */
2347         pieces = ast_alloca(count * sizeof(*pieces));
2348         for (ptr = tmp; *ptr; ptr++) {
2349                 if (*ptr == '/') {
2350                         *ptr = '\0';
2351                         pieces[piececount++] = ptr + 1;
2352                 }
2353         }
2354
2355         *fullpath = '\0';
2356         for (x = 0; x < piececount; x++) {
2357                 /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
2358                 strcat(fullpath, "/");
2359                 strcat(fullpath, pieces[x]);
2360                 res = mkdir(fullpath, mode);
2361                 if (res && errno != EEXIST)
2362                         return errno;
2363         }
2364         return 0;
2365 }
2366
2367 static int safe_mkdir(const char *base_path, char *path, int mode)
2368 {
2369         RAII_VAR(char *, absolute_path, NULL, ast_std_free);
2370
2371         absolute_path = realpath(path, NULL);
2372
2373         if (absolute_path) {
2374                 /* Path exists, but is it in the right place? */
2375                 if (!ast_begins_with(absolute_path, base_path)) {
2376                         return EPERM;
2377                 }
2378
2379                 /* It is in the right place! */
2380                 return 0;
2381         } else {
2382                 /* Path doesn't exist. */
2383
2384                 /* The slash terminating the subpath we're checking */
2385                 char *path_term = strchr(path, '/');
2386                 /* True indicates the parent path is within base_path */
2387                 int parent_is_safe = 0;
2388                 int res;
2389
2390                 while (path_term) {
2391                         RAII_VAR(char *, absolute_subpath, NULL, ast_std_free);
2392
2393                         /* Truncate the path one past the slash */
2394                         char c = *(path_term + 1);
2395                         *(path_term + 1) = '\0';
2396                         absolute_subpath = realpath(path, NULL);
2397
2398                         if (absolute_subpath) {
2399                                 /* Subpath exists, but is it safe? */
2400                                 parent_is_safe = ast_begins_with(
2401                                         absolute_subpath, base_path);
2402                         } else if (parent_is_safe) {
2403                                 /* Subpath does not exist, but parent is safe
2404                                  * Create it */
2405                                 res = mkdir(path, mode);
2406                                 if (res != 0) {
2407                                         ast_assert(errno != EEXIST);
2408                                         return errno;
2409                                 }
2410                         } else {
2411                                 /* Subpath did not exist, parent was not safe
2412                                  * Fail! */
2413                                 errno = EPERM;
2414                                 return errno;
2415                         }
2416                         /* Restore the path */
2417                         *(path_term + 1) = c;
2418                         /* Move on to the next slash */
2419                         path_term = strchr(path_term + 1, '/');
2420                 }
2421
2422                 /* Now to build the final path, but only if it's safe */
2423                 if (!parent_is_safe) {
2424                         errno = EPERM;
2425                         return errno;
2426                 }
2427
2428                 res = mkdir(path, mode);
2429                 if (res != 0 && errno != EEXIST) {
2430                         return errno;
2431                 }
2432
2433                 return 0;
2434         }
2435 }
2436
2437 int ast_safe_mkdir(const char *base_path, const char *path, int mode)
2438 {
2439         RAII_VAR(char *, absolute_base_path, NULL, ast_std_free);
2440         RAII_VAR(char *, p, NULL, ast_free);
2441
2442         if (base_path == NULL || path == NULL) {
2443                 errno = EFAULT;
2444                 return errno;
2445         }
2446
2447         p = ast_strdup(path);
2448         if (p == NULL) {
2449                 errno = ENOMEM;
2450                 return errno;
2451         }
2452
2453         absolute_base_path = realpath(base_path, NULL);
2454         if (absolute_base_path == NULL) {
2455                 return errno;
2456         }
2457
2458         return safe_mkdir(absolute_base_path, p, mode);
2459 }
2460
2461 static void utils_shutdown(void)
2462 {
2463         close(dev_urandom_fd);
2464         dev_urandom_fd = -1;
2465 #if defined(DEBUG_THREADS) && !defined(LOW_MEMORY)
2466         ast_cli_unregister_multiple(utils_cli, ARRAY_LEN(utils_cli));
2467 #endif
2468 }
2469
2470 int ast_utils_init(void)
2471 {
2472         dev_urandom_fd = open("/dev/urandom", O_RDONLY);
2473         base64_init();
2474 #ifdef DEBUG_THREADS
2475 #if !defined(LOW_MEMORY)
2476         ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
2477 #endif
2478 #endif
2479         ast_register_cleanup(utils_shutdown);
2480         return 0;
2481 }
2482
2483
2484 /*!
2485  *\brief Parse digest authorization header.
2486  *\return Returns -1 if we have no auth or something wrong with digest.
2487  *\note This function may be used for Digest request and responce header.
2488  * request arg is set to nonzero, if we parse Digest Request.
2489  * pedantic arg can be set to nonzero if we need to do addition Digest check.
2490  */
2491 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic) {
2492         char *c;
2493         struct ast_str *str = ast_str_create(16);
2494
2495         /* table of recognised keywords, and places where they should be copied */
2496         const struct x {
2497                 const char *key;
2498                 const ast_string_field *field;
2499         } *i, keys[] = {
2500                 { "username=", &d->username },
2501                 { "realm=", &d->realm },
2502                 { "nonce=", &d->nonce },
2503                 { "uri=", &d->uri },
2504                 { "domain=", &d->domain },
2505                 { "response=", &d->response },
2506                 { "cnonce=", &d->cnonce },
2507                 { "opaque=", &d->opaque },
2508                 /* Special cases that cannot be directly copied */
2509                 { "algorithm=", NULL },
2510                 { "qop=", NULL },
2511                 { "nc=", NULL },
2512                 { NULL, 0 },
2513         };
2514
2515         if (ast_strlen_zero(digest) || !d || !str) {
2516                 ast_free(str);
2517                 return -1;
2518         }
2519
2520         ast_str_set(&str, 0, "%s", digest);
2521
2522         c = ast_skip_blanks(ast_str_buffer(str));
2523
2524         if (strncasecmp(c, "Digest ", strlen("Digest "))) {
2525                 ast_log(LOG_WARNING, "Missing Digest.\n");
2526                 ast_free(str);
2527                 return -1;
2528         }
2529         c += strlen("Digest ");
2530
2531         /* lookup for keys/value pair */
2532         while (c && *c && *(c = ast_skip_blanks(c))) {
2533                 /* find key */
2534                 for (i = keys; i->key != NULL; i++) {
2535                         char *src, *separator;
2536                         int unescape = 0;
2537                         if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
2538                                 continue;
2539                         }
2540
2541                         /* Found. Skip keyword, take text in quotes or up to the separator. */
2542                         c += strlen(i->key);
2543                         if (*c == '"') {
2544                                 src = ++c;
2545                                 separator = "\"";
2546                                 unescape = 1;
2547                         } else {
2548                                 src = c;
2549                                 separator = ",";
2550                         }
2551                         strsep(&c, separator); /* clear separator and move ptr */
2552                         if (unescape) {
2553                                 ast_unescape_c(src);
2554                         }
2555                         if (i->field) {
2556                                 ast_string_field_ptr_set(d, i->field, src);
2557                         } else {
2558                                 /* Special cases that require additional procesing */
2559                                 if (!strcasecmp(i->key, "algorithm=")) {
2560                                         if (strcasecmp(src, "MD5")) {
2561                                                 ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src);
2562                                                 ast_free(str);
2563                                                 return -1;
2564                                         }
2565                                 } else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) {
2566                                         d->qop = 1;
2567                                 } else if (!strcasecmp(i->key, "nc=")) {
2568                                         unsigned long u;
2569                                         if (sscanf(src, "%30lx", &u) != 1) {
2570                                                 ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src);
2571                                                 ast_free(str);
2572                                                 return -1;
2573                                         }
2574                                         ast_string_field_set(d, nc, src);
2575                                 }
2576                         }
2577                         break;
2578                 }
2579                 if (i->key == NULL) { /* not found, try ',' */
2580                         strsep(&c, ",");
2581                 }
2582         }
2583         ast_free(str);
2584
2585         /* Digest checkout */
2586         if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
2587                 /* "realm" and "nonce" MUST be always exist */
2588                 return -1;
2589         }
2590
2591         if (!request) {
2592                 /* Additional check for Digest response */
2593                 if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) {
2594                         return -1;
2595                 }
2596
2597                 if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
2598                         return -1;
2599                 }
2600         }
2601
2602         return 0;
2603 }
2604
2605 #ifndef __AST_DEBUG_MALLOC
2606 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...)
2607 {
2608         int res;
2609         va_list ap;
2610
2611         va_start(ap, fmt);
2612         if ((res = vasprintf(ret, fmt, ap)) == -1) {
2613                 MALLOC_FAILURE_MSG;
2614         }
2615         va_end(ap);
2616
2617         return res;
2618 }
2619 #endif
2620
2621 int ast_get_tid(void)
2622 {
2623         int ret = -1;
2624 #if defined (__linux) && defined(SYS_gettid)
2625         ret = syscall(SYS_gettid); /* available since Linux 1.4.11 */
2626 #elif defined(__sun)
2627         ret = pthread_self();
2628 #elif defined(__APPLE__)
2629         ret = mach_thread_self();
2630         mach_port_deallocate(mach_task_self(), ret);
2631 #elif defined(__FreeBSD__) && defined(HAVE_SYS_THR_H)
2632         long lwpid;
2633         thr_self(&lwpid); /* available since sys/thr.h creation 2003 */
2634         ret = lwpid;
2635 #endif
2636         return ret;
2637 }
2638
2639 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
2640 {
2641         const char *envPATH = getenv("PATH");
2642         char *tpath, *path;
2643         struct stat unused;
2644         if (!envPATH) {
2645                 return NULL;
2646         }
2647         tpath = ast_strdupa(envPATH);
2648         while ((path = strsep(&tpath, ":"))) {
2649                 snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
2650                 if (!stat(fullpath, &unused)) {
2651                         return fullpath;
2652                 }
2653         }
2654         return NULL;
2655 }
2656
2657 void ast_do_crash(void)
2658 {
2659 #if defined(DO_CRASH)
2660         abort();
2661         /*
2662          * Just in case abort() doesn't work or something else super
2663          * silly, and for Qwell's amusement.
2664          */
2665         *((int *) 0) = 0;
2666 #endif  /* defined(DO_CRASH) */
2667 }
2668
2669 #if defined(AST_DEVMODE)
2670 void __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function)
2671 {
2672         /*
2673          * Attempt to put it into the logger, but hope that at least
2674          * someone saw the message on stderr ...
2675          */
2676         ast_log(__LOG_ERROR, file, line, function, "FRACK!, Failed assertion %s (%d)\n",
2677                 condition_str, condition);
2678         fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
2679                 condition_str, condition, line, function, file);
2680
2681         /* Generate a backtrace for the assert */
2682         ast_log_backtrace();
2683
2684         /*
2685          * Give the logger a chance to get the message out, just in case
2686          * we abort(), or Asterisk crashes due to whatever problem just
2687          * happened after we exit ast_assert().
2688          */
2689         usleep(1);
2690         ast_do_crash();
2691 }
2692 #endif  /* defined(AST_DEVMODE) */
2693
2694 char *ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
2695 {
2696         int x;
2697         char *os = s;
2698         if (maxlen < 18) {
2699                 if (s && (maxlen > 0)) {
2700                         *s = '\0';
2701                 }
2702         } else {
2703                 for (x = 0; x < 5; x++) {
2704                         sprintf(s, "%02hhx:", eid->eid[x]);
2705                         s += 3;
2706                 }
2707                 sprintf(s, "%02hhx", eid->eid[5]);
2708         }
2709         return os;
2710 }
2711
2712 void ast_set_default_eid(struct ast_eid *eid)
2713 {
2714 #if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_IFRU_IFRU_HWADDR)
2715         int s, x = 0;
2716         char eid_str[20];
2717         struct ifreq ifr;
2718         static const unsigned int MAXIF = 10;
2719
2720         s = socket(AF_INET, SOCK_STREAM, 0);
2721         if (s < 0) {
2722                 return;
2723         }
2724         for (x = 0; x < MAXIF; x++) {
2725                 static const char *prefixes[] = { "eth", "em" };
2726                 unsigned int i;
2727
2728                 for (i = 0; i < ARRAY_LEN(prefixes); i++) {
2729                         memset(&ifr, 0, sizeof(ifr));
2730                         snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", prefixes[i], x);
2731                         if (!ioctl(s, SIOCGIFHWADDR, &ifr)) {
2732                                 break;
2733                         }
2734                 }
2735
2736                 if (i == ARRAY_LEN(prefixes)) {
2737                         /* Try pciX#[1..N] */
2738                         for (i = 0; i < MAXIF; i++) {
2739                                 memset(&ifr, 0, sizeof(ifr));
2740                                 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "pci%d#%u", x, i);
2741                                 if (!ioctl(s, SIOCGIFHWADDR, &ifr)) {
2742                                         break;
2743                                 }
2744                         }
2745                         if (i == MAXIF) {
2746                                 continue;
2747                         }
2748                 }
2749
2750                 memcpy(eid, ((unsigned char *)&ifr.ifr_hwaddr) + 2, sizeof(*eid));
2751                 ast_debug(1, "Seeding global EID '%s' from '%s' using 'siocgifhwaddr'\n", ast_eid_to_str(eid_str, sizeof(eid_str), eid), ifr.ifr_name);
2752                 close(s);
2753                 return;
2754         }
2755         close(s);
2756 #else
2757 #if defined(ifa_broadaddr) && !defined(SOLARIS)
2758         char eid_str[20];
2759         struct ifaddrs *ifap;
2760
2761         if (getifaddrs(&ifap) == 0) {
2762                 struct ifaddrs *p;
2763                 for (p = ifap; p; p = p->ifa_next) {
2764                         if ((p->ifa_addr->sa_family == AF_LINK) && !(p->ifa_flags & IFF_LOOPBACK) && (p->ifa_flags & IFF_RUNNING)) {
2765                                 struct sockaddr_dl* sdp = (struct sockaddr_dl*) p->ifa_addr;
2766                                 memcpy(&(eid->eid), sdp->sdl_data + sdp->sdl_nlen, 6);
2767                                 ast_debug(1, "Seeding global EID '%s' from '%s' using 'getifaddrs'\n", ast_eid_to_str(eid_str, sizeof(eid_str), eid), p->ifa_name);
2768                                 freeifaddrs(ifap);
2769                                 return;
2770                         }
2771                 }
2772                 freeifaddrs(ifap);
2773         }
2774 #endif
2775 #endif
2776         ast_debug(1, "No ethernet interface found for seeding global EID. You will have to set it manually.\n");
2777 }
2778
2779 int ast_str_to_eid(struct ast_eid *eid, const char *s)
2780 {
2781         unsigned int eid_int[6];
2782         int x;
2783
2784         if (sscanf(s, "%2x:%2x:%2x:%2x:%2x:%2x", &eid_int[0], &eid_int[1], &eid_int[2],
2785                  &eid_int[3], &eid_int[4], &eid_int[5]) != 6) {
2786                         return -1;
2787         }
2788
2789         for (x = 0; x < 6; x++) {
2790                 eid->eid[x] = eid_int[x];
2791         }
2792
2793         return 0;
2794 }
2795
2796 int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
2797 {
2798         return memcmp(eid1, eid2, sizeof(*eid1));
2799 }