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