RTS API Documentation  1.10.11
switch_utils.h
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  * Seven Du <dujinfang@gmail.com>
28  *
29  *
30  * switch_utils.h -- Compatability and Helper Code
31  *
32  */
33 /*! \file switch_utils.h
34  \brief Compatability and Helper Code
35 
36  Just a miscelaneaous set of general utility/helper functions.
37 
38 */
39 #ifndef SWITCH_UTILS_H
40 #define SWITCH_UTILS_H
41 
42 #include <switch.h>
43 #include <math.h>
44 
46 
47 #define SWITCH_URL_UNSAFE "\r\n #%&+:;<=>?@[\\]^`{|}\""
48 
49 #define MAX_NETWORK_PORTS 10
50 
52  int port;
54  int min_port;
55  int max_port;
56 };
59 
60 static inline char *switch_get_hex_bytes(switch_byte_t *buf, switch_size_t datalen, char *new_buf, switch_size_t new_datalen)
61 {
62  switch_byte_t *p, *e;
63  char *pp, *ee;
64 
65  e = buf + datalen;
66  ee = new_buf + new_datalen;
67  pp = new_buf;
68 
69  for (p = buf; p < e && pp < ee - 4; p++) {
70  if (snprintf(pp, 4, "%.2x ", (int)*p) < 0) {
71  return NULL;
72  }
73  pp += 3;
74  }
75  *(pp-1) = '\0';
76 
77  return new_buf;
78 }
79 
80 
81 static inline uint32_t switch_round_to_step(uint32_t num, uint32_t step)
82 {
83  uint32_t r;
84  uint32_t x;
85 
86  if (!num) return 0;
87 
88  r = (num % step);
89  x = num - r;
90 
91  if (r > step / 2) {
92  x += step;
93  }
94 
95  return x;
96 }
97 
98 /* https://code.google.com/p/stringencoders/wiki/PerformanceAscii
99  http://www.azillionmonkeys.com/qed/asmexample.html
100 */
101 static inline uint32_t switch_toupper(uint32_t eax)
102 {
103 uint32_t ebx = (0x7f7f7f7ful & eax) + 0x05050505ul;
104 ebx = (0x7f7f7f7ful & ebx) + 0x1a1a1a1aul;
105  ebx = ((ebx & ~eax) >> 2 ) & 0x20202020ul;
106  return eax - ebx;
107 }
108 
109 /* https://code.google.com/p/stringencoders/wiki/PerformanceAscii
110  http://www.azillionmonkeys.com/qed/asmexample.html
111 */
112 static inline uint32_t switch_tolower(uint32_t eax)
113 {
114  uint32_t ebx = (0x7f7f7f7ful & eax) + 0x25252525ul;
115  ebx = (0x7f7f7f7ful & ebx) + 0x1a1a1a1aul;
116  ebx = ((ebx & ~eax) >> 2) & 0x20202020ul;
117  return eax + ebx;
118 }
119 
120 
121 #ifdef FS_64BIT
122 
123 /* https://code.google.com/p/stringencoders/wiki/PerformanceAscii
124  http://www.azillionmonkeys.com/qed/asmexample.html
125 */
126 static inline uint64_t switch_toupper64(uint64_t eax)
127 {
128 uint64_t ebx = (0x7f7f7f7f7f7f7f7full & eax) + 0x0505050505050505ull;
129  ebx = (0x7f7f7f7f7f7f7f7full & ebx) + 0x1a1a1a1a1a1a1a1aull;
130  ebx = ((ebx & ~eax) >> 2 ) & 0x2020202020202020ull;
131  return eax - ebx;
132 }
133 
134 /* https://code.google.com/p/stringencoders/wiki/PerformanceAscii
135  http://www.azillionmonkeys.com/qed/asmexample.html
136 */
137 static inline uint64_t switch_tolower64(uint64_t eax)
138 {
139  uint64_t ebx = (0x7f7f7f7f7f7f7f7full & eax) + 0x2525252525252525ull;
140  ebx = (0x7f7f7f7f7f7f7f7full & ebx) + 0x1a1a1a1a1a1a1a1aull;
141  ebx = ((ebx & ~eax) >> 2) & 0x2020202020202020ull;
142  return eax + ebx;
143 }
144 
145 static inline void switch_toupper_max(char *s)
146 {
147  uint64_t *b,*p;
148  char *c;
149  size_t l;
150 
151  l = strlen(s);
152 
153  p = (uint64_t *) s;
154 
155  while (l > 8) {
156  b = p;
157  *b = (uint64_t) switch_toupper64(*b);
158  b++;
159  p++;
160  l -= 8;
161  }
162 
163  c = (char *)p;
164 
165  while(l > 0) {
166  *c = (char) switch_toupper(*c);
167  c++;
168  l--;
169  }
170 
171 }
172 
173 static inline void switch_tolower_max(char *s)
174 {
175  uint64_t *b,*p;
176  char *c;
177  size_t l;
178 
179  l = strlen(s);
180 
181  p = (uint64_t *) s;
182 
183  while (l > 8) {
184  b = p;
185  *b = (uint64_t) switch_tolower64(*b);
186  b++;
187  p++;
188  l -= 8;
189  }
190 
191  c = (char *)p;
192 
193  while(l > 0) {
194  *c = (char) switch_tolower(*c);
195  c++;
196  l--;
197  }
198 
199 }
200 
201 #else
202 
203 static inline void switch_toupper_max(char *s)
204 {
205  uint32_t *b,*p;
206  char *c;
207  size_t l;
208 
209  l = strlen(s);
210 
211  p = (uint32_t *) s;
212 
213  while (l > 4) {
214  b = p;
215  *b = (uint32_t) switch_toupper(*b);
216  b++;
217  p++;
218  l -= 4;
219  }
220 
221  c = (char *)p;
222 
223  while(l > 0) {
224  *c = (char) switch_toupper(*c);
225  c++;
226  l--;
227  }
228 
229 }
230 
231 static inline void switch_tolower_max(char *s)
232 {
233  uint32_t *b,*p;
234  char *c;
235  size_t l;
236 
237  l = strlen(s);
238 
239  p = (uint32_t *) s;
240 
241  while (l > 4) {
242  b = p;
243  *b = (uint32_t) switch_tolower(*b);
244  b++;
245  p++;
246  l -= 4;
247  }
248 
249  c = (char *)p;
250 
251  while(l > 0) {
252  *c = (char) switch_tolower(*c);
253  c++;
254  l--;
255  }
256 
257 }
258 #endif
259 
260 
261 
262 
265 SWITCH_DECLARE(int) switch_isalnum(int c);
266 SWITCH_DECLARE(int) switch_isalpha(int c);
267 SWITCH_DECLARE(int) switch_iscntrl(int c);
268 SWITCH_DECLARE(int) switch_isdigit(int c);
269 SWITCH_DECLARE(int) switch_isgraph(int c);
270 SWITCH_DECLARE(int) switch_islower(int c);
271 SWITCH_DECLARE(int) switch_isprint(int c);
272 SWITCH_DECLARE(int) switch_ispunct(int c);
273 SWITCH_DECLARE(int) switch_isspace(int c);
274 SWITCH_DECLARE(int) switch_isupper(int c);
275 SWITCH_DECLARE(int) switch_isxdigit(int c);
276 
277 typedef union{
278  uint32_t v4;
279  struct in6_addr v6;
280 } ip_t;
281 
283 
284 
286 
287 #define switch_goto_status(_status, _label) status = _status; goto _label
288 #define switch_goto_int(_n, _i, _label) _n = _i; goto _label
289 #define switch_samples_per_packet(rate, interval) ((uint32_t)((float)rate / (1000.0f / (float)interval)))
290 #define SWITCH_SMAX 32767
291 #define SWITCH_SMIN -32768
292 #define switch_normalize_to_16bit(n) if (n > SWITCH_SMAX) n = SWITCH_SMAX; else if (n < SWITCH_SMIN) n = SWITCH_SMIN;
293 #define switch_codec2str(codec,buf,len) snprintf(buf, len, "%s@%uh@%ui", \
294  codec->implementation->iananame, \
295  codec->implementation->samples_per_second, \
296  codec->implementation->microseconds_per_packet / 1000)
297 
298 
299 
300 /*!
301  \brief Test for NULL or zero length string
302  \param s the string to test
303  \return true value if the string is NULL or zero length
304 */
305 _Check_return_ static inline int _zstr(_In_opt_z_ const char *s)
306 {
307  if (!s) return 1;
308  if (*s == '\0') return 1;
309  return 0;
310 }
311 #ifdef _PREFAST_
312 #define zstr(x) (_zstr(x) ? 1 : __analysis_assume(x),0)
313 #else
314 #define zstr(x) _zstr(x)
315 #endif
316 #define switch_strlen_zero(x) zstr(x)
317 #define switch_strlen_zero_buf(x) zstr_buf(x)
318 #define zstr_buf(s) (*(s) == '\0')
319 static inline switch_bool_t switch_is_moh(const char *s)
320 {
321  if (zstr(s) || !strcasecmp(s, "silence") || !strcasecmp(s, "indicate_hold")) {
322  return SWITCH_FALSE;
323  }
324  return SWITCH_TRUE;
325 }
326 
327 
328 #define zset(_a, _b) if (!zstr(_b)) _a = _b
329 
330 
331 /* find a character (find) in a string (in) and return a pointer to that point in the string where the character was found
332  using the array (allowed) as allowed non-matching characters, when (allowed) is NULL, behaviour should be identical to strchr()
333  */
334 static inline char *switch_strchr_strict(const char *in, char find, const char *allowed)
335 {
336  const char *p;
337 
338  switch_assert(in);
339 
340  p = in;
341 
342  if (!*p) return NULL;
343 
344  while(p && *p) {
345  const char *a = allowed;
346  int acceptable = 0;
347 
348  if (*p == find) break;
349 
350  if (!a) {
351  acceptable = 1;
352  } else {
353 
354  while(a && *a) {
355 
356  if (*p == *a) {
357  acceptable = 1;
358  break;
359  }
360 
361  a++;
362  }
363 
364  }
365 
366  if (!acceptable) return NULL;
367 
368  p++;
369  }
370 
371  return (char *) p;
372 }
373 
374 #define switch_arraylen(_a) (sizeof(_a) / sizeof(_a[0]))
375 #define switch_split(_data, _delim, _array) switch_separate_string(_data, _delim, _array, switch_arraylen(_array))
376 #define switch_split_cheap(_data, _delim, _array, _larray) switch_separate_string_cheap(_data, _delim, (const char **)_array, _larray, switch_arraylen(_array))
377 
378 #define switch_is_valid_rate(_tmp) (_tmp == 8000 || _tmp == 12000 || _tmp == 16000 || _tmp == 24000 || _tmp == 32000 || _tmp == 11025 || _tmp == 22050 || _tmp == 44100 || _tmp == 48000)
379 
380 
381 #ifdef _MSC_VER
382 #pragma warning(disable:6011)
383 #endif
384 static inline int switch_string_has_escaped_data(const char *in)
385 {
386  const char *i;
387 
388  switch_assert(in);
389 
390  i = strchr(in, '\\');
391 
392  while (i && *i == '\\') {
393  i++;
394  if (*i == '\\' || *i == 'n' || *i == 's' || *i == 't' || *i == '\'') {
395  return 1;
396  }
397  i = strchr(i, '\\');
398  }
399 
400  return 0;
401 }
402 #ifdef _MSC_VER
403 #pragma warning(default:6011)
404 #endif
405 
406 SWITCH_DECLARE(switch_status_t) switch_b64_encode(unsigned char *in, switch_size_t ilen, unsigned char *out, switch_size_t olen);
407 SWITCH_DECLARE(switch_size_t) switch_b64_decode(const char *in, char *out, switch_size_t olen);
408 SWITCH_DECLARE(char *) switch_amp_encode(char *s, char *buf, switch_size_t len);
409 
410 
411 
412 static inline char *switch_print_bits(const unsigned char *byte, char *buf, switch_size_t buflen)
413 {
414  int i;
415  switch_size_t j = 0, k = 0, l = 0;
416 
417  while(k < buflen) {
418  l = 0;
419  for (i = 7; i >= 0; i--) {
420  buf[j++] = (*byte & (1 << i)) ? '1' : '0';
421  if (++l % 4 == 0) {
422  buf[j++] = ' ';
423  }
424  }
425  k++;
426  byte++;
427  }
428 
429  if (buf[j-1] == ' ') j--;
430  buf[j++] = '\0';
431  return buf;
432 }
433 
434 
435 
436 
437 static inline switch_bool_t switch_is_digit_string(const char *s)
438 {
439 
440  while (s && *s) {
441  if (*s < 48 || *s > 57) {
442  return SWITCH_FALSE;
443  }
444  s++;
445  }
446 
447  return SWITCH_TRUE;
448 }
449 
450 static inline char switch_itodtmf(char i)
451 {
452  char r = i;
453 
454  if (i > 9 && i < 14) {
455  r += 55;
456  } else {
457  r += 48;
458  }
459 
460  return r;
461 }
462 
463 static inline int switch_dtmftoi(char *s)
464 {
465  int r;
466 
467  switch_assert(s);
468 
469  if (!(r = atoi(s))) {
470  int l = tolower((unsigned char)*s);
471  if (l > 96 && l < 101) {
472  r = l - 87;
473  }
474  }
475 
476  return r;
477 }
478 
479 static inline uint32_t switch_known_bitrate(switch_payload_t payload)
480 {
481  switch(payload) {
482  case 0: /* PCMU */ return 64000;
483  case 3: /* GSM */ return 13200;
484  case 4: /* G723 */ return 6300;
485  case 7: /* LPC */ return 2400;
486  case 8: /* PCMA */ return 64000;
487  case 9: /* G722 */ return 64000;
488  case 18: /* G729 */ return 8000;
489  default: break;
490  }
491 
492  return 0;
493 }
494 
498 
502 
503 /*! \brief Check if a 32 bit unsigned number is in a range.
504  * \param str string to check. Should not contain non-digit characters.
505  * \param from start of range including this number
506  * \param to end of range including this number
507  * \return true or false
508  */
509 SWITCH_DECLARE(switch_bool_t) switch_is_uint_in_range(const char *str, unsigned int from, unsigned int to);
512 SWITCH_DECLARE(char *) switch_find_parameter(const char *str, const char *param, switch_memory_pool_t *pool);
513 
514 /*!
515  \brief Evaluate the truthfullness of a string expression
516  \param expr a string expression
517  \return true or false
518 */
519 static inline switch_bool_t switch_true(const char *expr)
520 {
521  return ((expr && ( !strcasecmp(expr, "yes") ||
522  !strcasecmp(expr, "on") ||
523  !strcasecmp(expr, "true") ||
524  !strcasecmp(expr, "t") ||
525  !strcasecmp(expr, "enabled") ||
526  !strcasecmp(expr, "active") ||
527  !strcasecmp(expr, "allow") ||
528  (switch_is_number(expr) && atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE);
529 }
530 
531 static inline switch_byte_t switch_true_byte(const char *expr)
532 {
533  return (switch_byte_t)switch_true(expr);
534 }
535 
536 #define switch_true_buf(expr)\
537 ((( !strcasecmp(expr, "yes") ||\
538 !strcasecmp(expr, "on") ||\
539 !strcasecmp(expr, "true") ||\
540 !strcasecmp(expr, "t") ||\
541 !strcasecmp(expr, "enabled") ||\
542 !strcasecmp(expr, "active") ||\
543 !strcasecmp(expr, "allow") ||\
544 (switch_is_number(expr) && atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE)
545 
546 /*!
547  \brief Evaluate the falsefullness of a string expression
548  \param expr a string expression
549  \return true or false
550 */
551 static inline int switch_false(const char *expr)
552 {
553  return ((expr && ( !strcasecmp(expr, "no") ||
554  !strcasecmp(expr, "off") ||
555  !strcasecmp(expr, "false") ||
556  !strcasecmp(expr, "f") ||
557  !strcasecmp(expr, "disabled") ||
558  !strcasecmp(expr, "inactive") ||
559  !strcasecmp(expr, "disallow") ||
560  (switch_is_number(expr) && !atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE);
561 }
562 
563 
564 SWITCH_DECLARE(switch_status_t) switch_resolve_host(const char *host, char *buf, size_t buflen);
565 
566 
567 /*!
568  \brief find local ip of the box
569  \param buf the buffer to write the ip address found into
570  \param len the length of the buf
571  \param mask the CIDR found (AF_INET only)
572  \param family the address family to return (AF_INET or AF_INET6)
573  \return SWITCH_STATUS_SUCCESSS for success, otherwise failure
574 */
576  char *buf, _In_ int len, _In_opt_ int *mask, _In_ int family);
577 
578 /*!
579  \brief find primary ip of the specified interface
580  \param buf the buffer to write the ip address found into
581  \param len the length of the buf
582  \param mask the CIDR found (AF_INET only)
583  \param ifname interface name to check
584  \param family the address family to return (AF_INET or AF_INET6)
585  \return SWITCH_STATUS_SUCCESSS for success, otherwise failure
586 */
588  char *buf, _In_ int len, _In_opt_ int *mask, _In_ const char *ifname, _In_ int family);
589 
590 /*!
591  \brief find the char representation of an ip adress
592  \param buf the buffer to write the ip adress found into
593  \param len the length of the buf
594  \param sa the struct sockaddr * to get the adress from
595  \param salen the length of sa
596  \return the ip adress string
597 */
598 SWITCH_DECLARE(char *) get_addr(char *buf, switch_size_t len, struct sockaddr *sa, socklen_t salen);
599 SWITCH_DECLARE(char *) get_addr6(char *buf, switch_size_t len, struct sockaddr_in6 *sa, socklen_t salen);
600 
604 
605 /*!
606  \brief get the port number of an ip address
607  \param sa the struct sockaddr * to get the port from
608  \return the ip adress string
609 */
610 SWITCH_DECLARE(unsigned short) get_port(struct sockaddr *sa);
611 
612 /*!
613  \brief flags to be used with switch_build_uri()
614  */
619  };
620 
621 /*!
622  \brief build a URI string from components
623  \param uri output string
624  \param size maximum size of output string (including trailing null)
625  \param scheme URI scheme
626  \param user user part or null if none
627  \param sa host address
628  \param flags logical OR-ed combination of flags from \ref switch_uri_flags
629  \return number of characters printed (not including the trailing null)
630  */
631 SWITCH_DECLARE(int) switch_build_uri(char *uri, switch_size_t size, const char *scheme, const char *user, const switch_sockaddr_t *sa, int flags);
632 
633 #define SWITCH_STATUS_IS_BREAK(x) (x == SWITCH_STATUS_BREAK || x == 730035 || x == 35 || x == SWITCH_STATUS_INTR)
634 
635 
636 #ifdef _MSC_VER
637 
638 #define switch_errno() WSAGetLastError()
639 
640 static inline int switch_errno_is_break(int errcode)
641 {
642  return errcode == WSAEWOULDBLOCK || errcode == WSAEINPROGRESS || errcode == WSAEINTR;
643 }
644 
645 #else
646 
647 #define switch_errno() errno
648 
649 static inline int switch_errno_is_break(int errcode)
650 {
651  return errcode == EAGAIN || errcode == EWOULDBLOCK || errcode == EINPROGRESS || errcode == EINTR || errcode == ETIMEDOUT;
652 }
653 
654 #endif
655 
656 
657 /*!
658  \brief Return a printable name of a switch_priority_t
659  \param priority the priority to get the name of
660  \return the printable form of the priority
661 */
663 
664 /*!
665  \brief Return the RFC2833 character based on an event id
666  \param event the event id to convert
667  \return the character represented by the event or null for an invalid event
668 */
669 SWITCH_DECLARE(char) switch_rfc2833_to_char(int event);
670 
671 /*!
672  \brief Return the RFC2833 event based on an key character
673  \param key the charecter to encode
674  \return the event id for the specified character or -1 on an invalid input
675 */
676 SWITCH_DECLARE(unsigned char) switch_char_to_rfc2833(char key);
677 
678 /*!
679  \brief determine if a character is a valid DTMF key
680  \param key the key to test
681  \return TRUE or FALSE
682  */
683 #define is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119 || key == 70 || key == 102)
684 
685 #define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1)
686 #define end_of_p(_s) (*_s == '\0' ? _s : _s + strlen(_s) - 1)
687 /*!
688  \brief Test for the existance of a flag on an arbitary object
689  \param obj the object to test
690  \param flag the or'd list of flags to test
691  \return true value if the object has the flags defined
692 */
693 #define switch_test_flag(obj, flag) ((obj)->flags & flag)
694 
695 /*!
696  \brief Set a flag on an arbitrary object
697  \param obj the object to set the flags on
698  \param flag the or'd list of flags to set
699 */
700 #define switch_set_flag(obj, flag) (obj)->flags |= (flag)
701 
702 /*!
703  \brief Set a flag on an arbitrary object while locked
704  \param obj the object to set the flags on
705  \param flag the or'd list of flags to set
706 */
707 #define switch_set_flag_locked(obj, flag) assert((obj)->flag_mutex != NULL); \
708 switch_mutex_lock((obj)->flag_mutex); \
709 (obj)->flags |= (flag);\
710 switch_mutex_unlock((obj)->flag_mutex);
711 
712 /*!
713  \brief Clear a flag on an arbitrary object
714  \param obj the object to test
715  \param flag the or'd list of flags to clear
716 */
717 #define switch_clear_flag_locked(obj, flag) switch_mutex_lock((obj)->flag_mutex); (obj)->flags &= ~(flag); switch_mutex_unlock((obj)->flag_mutex);
718 
719 /*!
720  \brief Clear a flag on an arbitrary object while locked
721  \param obj the object to test
722  \param flag the or'd list of flags to clear
723 */
724 #define switch_clear_flag(obj, flag) (obj)->flags &= ~(flag)
725 
726 /*!
727  \brief Copy flags from one arbitrary object to another
728  \param dest the object to copy the flags to
729  \param src the object to copy the flags from
730  \param flags the flags to copy
731 */
732 #define switch_copy_flags(dest, src, flags) (dest)->flags &= ~(flags); (dest)->flags |= ((src)->flags & (flags))
733 
734 #define switch_set_string(_dst, _src) switch_copy_string(_dst, _src, sizeof(_dst))
735 
736 
737 static inline char *switch_sanitize_number(char *number)
738 {
739  char *p = number, *q;
740  char warp[] = "/:";
741  int i;
742 
743  switch_assert(number);
744 
745  if (!(strchr(p, '/') || strchr(p, ':') || strchr(p, '@') || strchr(p, '%'))) {
746  return number;
747  }
748 
749  while ((q = strrchr(p, '@')))
750  *q = '\0';
751 
752  while ((q = strrchr(p, '%')))
753  *q = '\0';
754 
755  for (i = 0; i < (int) strlen(warp); i++) {
756  while (p && (q = strchr(p, warp[i])))
757  p = q + 1;
758  }
759 
760  return p;
761 }
762 
763 static inline switch_bool_t switch_string_var_check(char *s, switch_bool_t disable)
764 {
765  char *p;
766  char *dol = NULL;
767 
768  for (p = s; p && *p; p++) {
769  if (*p == '$') {
770  dol = p;
771  } else if (dol) {
772  if (*p == '{') {
773  if (disable) {
774  *dol = '%';
775  dol = NULL;
776  } else {
777  return SWITCH_TRUE;
778  }
779  } else if (*p != '\\') {
780  dol = NULL;
781  }
782  }
783  }
784  return SWITCH_FALSE;
785 }
786 
787 
788 static inline switch_bool_t switch_string_var_check_const(const char *s)
789 {
790  const char *p;
791  int dol = 0;
792 
793  for (p = s; p && *p; p++) {
794  if (*p == '$') {
795  dol = 1;
796  } else if (dol) {
797  if (*p == '{') {
798  return SWITCH_TRUE;
799  } else if (*p != '\\') {
800  dol = 0;
801  }
802  }
803  }
804  return SWITCH_FALSE;
805 }
806 
807 static inline char *switch_var_clean_string(char *s)
808 {
810  return s;
811 }
812 
813 static inline char *switch_clean_string(char *s)
814 {
815  char *p;
816  for (p = s; p && *p; p++) {
817  uint8_t x = (uint8_t) * p;
818  if ((x < 32) && x != '\n' && x != '\r') {
819  *p = ' ';
820  }
821  }
822 
823  return s;
824 }
825 
826 
827 static inline char *switch_clean_name_string(char *s)
828 {
829  char *p;
830  for (p = s; p && *p; p++) {
831  uint8_t x = (uint8_t) * p;
832  if ((x < 32) || x == '\'' || x == '"' || x == '<' || x == '>' || x == '\\' || x == ':' || x == '@' || x == '/') {
833  *p = ' ';
834  }
835  if ( (p == s) && (*p == ' ') ) {
836  s++;
837  }
838  }
839 
840  return s;
841 }
842 
843 
844 
845 /*!
846  \brief Turn a string into an integer (default if NULL)
847  \param nptr the string
848  \param dft the default
849  \return the integer version of the string or the default
850 */
851 static inline int switch_safe_atoi(const char *nptr, int dft)
852 {
853  return nptr ? atoi(nptr) : dft;
854 }
855 
856 
857 /*!
858  \brief Turn a string into a long integer (default if NULL)
859  \param nptr the string
860  \param dft the default
861  \return the long integer version of the string or the default
862 */
863 static inline long int switch_safe_atol(const char *nptr, long int dft)
864 {
865  return nptr ? atol(nptr) : dft;
866 }
867 
868 
869 /*!
870  \brief Turn a string into a long long integer (default if NULL)
871  \param nptr the string
872  \param dft the default
873  \return the long long integer version of the string or the default
874 */
875 static inline long long int switch_safe_atoll(const char *nptr, long long int dft)
876 {
877  return nptr ? atoll(nptr) : dft;
878 }
879 
880 
881 /*!
882  \brief Free a pointer and set it to NULL unless it already is NULL
883  \param it the pointer
884 */
885 #define switch_safe_free(it) if (it) {free(it);it=NULL;}
886 
887 static inline char *switch_safe_strdup(const char *it)
888 {
889  if (it) {
890  return strdup(it);
891  }
892 
893  return NULL;
894 }
895 
896 
897 #ifdef _MSC_VER
898 #pragma warning(disable:6011)
899 #endif
900 static inline char *switch_lc_strdup(const char *it)
901 {
902  char *dup;
903 
904  if (it) {
905  dup = strdup(it);
906  switch_tolower_max(dup);
907  return dup;
908  }
909 
910  return NULL;
911 }
912 
913 
914 static inline char *switch_uc_strdup(const char *it)
915 {
916  char *dup;
917 
918  if (it) {
919  dup = strdup(it);
920  switch_toupper_max(dup);
921  return dup;
922  }
923 
924  return NULL;
925 }
926 #ifdef _MSC_VER
927 #pragma warning(default:6011)
928 #endif
929 
930 
931 /*!
932  \brief Test if one string is inside another with extra case checking
933  \param s the inner string
934  \param q the big string
935  \return SWITCH_TRUE or SWITCH_FALSE
936 */
937 static inline switch_bool_t switch_strstr(char *s, char *q)
938 {
939  char *p, *S = NULL, *Q = NULL;
941 
942  if (!s || !q) {
943  return SWITCH_FALSE;
944  }
945 
946  if (strstr(s, q)) {
947  return SWITCH_TRUE;
948  }
949 
950  S = strdup(s);
951 
952  switch_assert(S != NULL);
953 
954  for (p = S; p && *p; p++) {
955  *p = (char) switch_toupper(*p);
956  }
957 
958  if (strstr(S, q)) {
959  tf = SWITCH_TRUE;
960  goto done;
961  }
962 
963  Q = strdup(q);
964  switch_assert(Q != NULL);
965 
966  for (p = Q; p && *p; p++) {
967  *p = (char) switch_toupper(*p);
968  }
969 
970  if (strstr(s, Q)) {
971  tf = SWITCH_TRUE;
972  goto done;
973  }
974 
975  if (strstr(S, Q)) {
976  tf = SWITCH_TRUE;
977  goto done;
978  }
979 
980  done:
981  switch_safe_free(S);
982  switch_safe_free(Q);
983 
984  return tf;
985 }
986 
987 
988 /*!
989  \brief Make a null string a blank string instead
990  \param s the string to test
991  \return the original string or blank string.
992 */
993 #define switch_str_nil(s) (s ? s : "")
994 
995 /*!
996  \brief Wait a desired number of microseconds and yield the CPU
997 */
998 #define switch_yield(ms) switch_sleep(ms);
999 
1000 /*!
1001  \brief Converts a string representation of a date into a switch_time_t
1002  \param in the string
1003  \return the epoch time in usec
1004 */
1006 #define switch_time_from_sec(sec) ((switch_time_t)(sec) * 1000000)
1007 
1008 /*!
1009  \brief Declares a function designed to set a dynamic global string
1010  \param fname the function name to declare
1011  \param vname the name of the global pointer to modify with the new function
1012 */
1013 #define SWITCH_DECLARE_GLOBAL_STRING_FUNC(fname, vname) static void fname(const char *string) { if (!string) return;\
1014  if (vname) {free(vname); vname = NULL;}vname = strdup(string);} static void fname(const char *string)
1015 
1016 /*!
1017  \brief Separate a string into an array based on a character delimiter
1018  \param buf the string to parse
1019  \param delim the character delimiter
1020  \param array the array to split the values into
1021  \param arraylen the max number of elements in the array
1022  \return the number of elements added to the array
1023 */
1024 SWITCH_DECLARE(unsigned int) switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen);
1025 SWITCH_DECLARE(unsigned int) switch_separate_string_string(char *buf, char *delim, _Post_count_(return) char **array, unsigned int arraylen);
1026 
1027 /*!
1028  \brief Separate a string into an array based on a character delimiter, no memory corruption!
1029  DOESN'T support removing quotes like what's in switch_separate_string()!
1030  \param buf the string to parse
1031  \param delim the character delimiter
1032  \param array the array to split the values into
1033  \param larray the array that hold the lenth of each element
1034  \param arraylen the max number of elements in the array
1035  \return the number of elements added to the array
1036 */
1037 SWITCH_DECLARE(unsigned int) switch_separate_string_cheap(_In_ const char *buf, char delim, _Post_count_(return) const char **array, _Post_count_(return) unsigned int larray[], unsigned int arraylen);
1038 
1039 SWITCH_DECLARE(char *) switch_strip_spaces(char *str, switch_bool_t dup);
1040 SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str);
1041 SWITCH_DECLARE(char *) switch_strip_commas(char *in, char *out, switch_size_t len);
1042 SWITCH_DECLARE(char *) switch_strip_nonnumerics(char *in, char *out, switch_size_t len);
1043 SWITCH_DECLARE(char *) switch_separate_paren_args(char *str);
1044 SWITCH_DECLARE(const char *) switch_stristr(const char *instr, const char *str);
1046 SWITCH_DECLARE(char *) switch_replace_char(char *str, char from, char to, switch_bool_t dup);
1047 SWITCH_DECLARE(switch_bool_t) switch_ast2regex(const char *pat, char *rbuf, size_t len);
1049 
1050 /*!
1051  \brief Escape a string by prefixing a list of characters with an escape character
1052  \param pool a memory pool to use
1053  \param in the string
1054  \param delim the list of characters to escape
1055  \param esc the escape character
1056  \return the escaped string
1057 */
1058 SWITCH_DECLARE(char *) switch_escape_char(switch_memory_pool_t *pool, char *in, const char *delim, char esc);
1059 
1060 SWITCH_DECLARE(char *) switch_escape_string(const char *in, char *out, switch_size_t outlen);
1062 
1063 /*!
1064  \brief Wait for a socket
1065  \param poll the pollfd to wait on
1066  \param ms the number of milliseconds to wait
1067  \return the requested condition
1068 */
1070 
1071 /*!
1072  \brief Create a pointer to the file name in a given file path eliminating the directory name
1073  \return the pointer to the next character after the final / or \\ characters
1074 */
1075 SWITCH_DECLARE(const char *) switch_cut_path(const char *in);
1076 
1077 SWITCH_DECLARE(char *) switch_string_replace(const char *string, const char *search, const char *replace);
1078 SWITCH_DECLARE(switch_status_t) switch_string_match(const char *string, size_t string_len, const char *search, size_t search_len);
1079 SWITCH_DECLARE(int) switch_strcasecmp_any(const char *str, ...);
1080 
1081 /*!
1082  \brief Quote shell argument
1083  \param string the string to quote (example: a ' b"' c)
1084  \return the quoted string (gives: 'a '\'' b"'\'' c' for unices, "a ' b ' c" for MS Windows), should be freed
1085 */
1086 SWITCH_DECLARE(char *) switch_util_quote_shell_arg(const char *string);
1087 
1088 /*!
1089  \brief Quote shell argument, allocating from pool if provided
1090  \param string the string to quote (example: a ' b"' c)
1091  \param pool a memory pool to use
1092  \return the quoted string (gives: 'a '\'' b"'\'' c' for unices, "a ' b ' c" for MS Windows), if pool not provided, returned value should be freed
1093 */
1095 
1096 
1097 #define SWITCH_READ_ACCEPTABLE(status) (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)
1098 
1099 
1100 static inline int32_t switch_calc_bitrate(int w, int h, float quality, double fps)
1101 {
1102  int r;
1103 
1104  if (quality == 0) {
1105  quality = 1;
1106  }
1107 
1108  /* KUSH GAUGE*/
1109 
1110  if (!fps) fps = 15;
1111 
1112  r = (int32_t)((double)(w * h * fps * quality) * 0.07) / 1000;
1113 
1114  if (!quality) r /= 2;
1115 
1116  if (quality < 0.0f) {
1117  r = (int) ((float)r * quality);
1118  }
1119 
1120  return r;
1121 
1122 }
1123 
1124 static inline void switch_calc_fps(switch_fps_t *fpsP, float fps, int samplerate)
1125 {
1126  /*
1127  implicit/truncf() - leave us with equal-or-smaller ms and thus equal-or-bigger fps, which is better for quality (than roundf()).
1128  also equal-or-bigger fps is better for things like (int)fps
1129  */
1130  fpsP->ms = (int)(1000.0f / fps);
1131  fpsP->fps = 1000.0f / fpsP->ms;
1132  fpsP->samples = (int)(samplerate / 1000 * fpsP->ms); // samplerate 99.99% is a factor of 1000, so we safe here with integer div by 1000
1133  return;
1134 }
1135 #define switch_calc_video_fps(fpsP, fps) switch_calc_fps(fpsP, fps, 90000)
1136 
1137 static inline int32_t switch_parse_bandwidth_string(const char *bwv)
1138 {
1139  float bw = 0;
1140 
1141  if (!bwv) return 0;
1142 
1143  if (!strcasecmp(bwv, "auto")) {
1144  return -1;
1145  }
1146 
1147  if ((bw = (float) atof(bwv))) {
1148  if (bw < 0) return 0;
1149 
1150  if (strstr(bwv, "KB")) {
1151  bw *= 8;
1152  } else if (strstr(bwv, "mb")) {
1153  bw *= 1024;
1154  } else if (strstr(bwv, "MB")) {
1155  bw *= 8192;
1156  }
1157  }
1158 
1159  return (int32_t) roundf(bw);
1160 }
1161 
1162 static inline uint32_t switch_parse_cpu_string(const char *cpu)
1163 {
1164  int cpu_count = switch_core_cpu_count();
1165  int ncpu;
1166 
1167  if (!cpu) return 1;
1168 
1169  if (!strcasecmp(cpu, "auto")) {
1170  return (uint32_t)((cpu_count * 3) / 2);
1171  }
1172 
1173  if (!strncasecmp(cpu, "cpu/", 4)) { /* cpu/2 or cpu/2/<max> */
1174  const char *has_max = cpu;
1175  float divisor;
1176  int max = cpu_count;
1177 
1178  cpu +=4;
1179 
1180  has_max = strchr(cpu, '/');
1181 
1182  if (has_max > cpu) {
1183  max = atoi(has_max + 1);
1184  }
1185 
1186  divisor = (float)atof(cpu);
1187 
1188  if (divisor <= 0) divisor = 1;
1189 
1190  ncpu = (int)(cpu_count / divisor);
1191 
1192  if (ncpu <= 0) return 1;
1193 
1194  if (ncpu > max) return (uint32_t)max;
1195 
1196  return (uint32_t)ncpu;
1197  } else if (!strcasecmp(cpu, "cpu")) {
1198  ncpu = cpu_count;
1199  } else {
1200  ncpu = atoi(cpu);
1201 
1202  if (strrchr(cpu, '%')) {
1203  ncpu = (int) (cpu_count * ((float)ncpu / 100));
1204  }
1205  }
1206 
1207  if (ncpu > cpu_count) return (uint32_t)cpu_count;
1208 
1209  if (ncpu <= 0) return 1;
1210 
1211  return ncpu;
1212 }
1213 
1214 static inline int switch_needs_url_encode(const char *s)
1215 {
1216  const char hex[] = "0123456789ABCDEF";
1217  const char *p, *e = end_of_p(s);
1218 
1219 
1220  for(p = s; p && *p; p++) {
1221  if (*p == '%' && e-p > 1) {
1222  if (strchr(hex, *(p+1)) && strchr(hex, *(p+2))) {
1223  p++;
1224  continue;
1225  }
1226  }
1227 
1228  if (strchr(SWITCH_URL_UNSAFE, *p)) {
1229  return 1;
1230  }
1231  }
1232 
1233  return 0;
1234 }
1235 
1236 SWITCH_DECLARE(char *) switch_url_encode_opt(const char *url, char *buf, size_t len, switch_bool_t double_encode);
1237 SWITCH_DECLARE(char *) switch_url_encode(const char *url, char *buf, size_t len);
1238 SWITCH_DECLARE(char *) switch_url_decode(char *s);
1239 
1240 SWITCH_DECLARE(char *) switch_core_url_encode_opt(switch_memory_pool_t *pool, const char *url, switch_bool_t double_encode);
1241 SWITCH_DECLARE(char *) switch_core_url_encode(switch_memory_pool_t *pool, const char *url);
1242 SWITCH_DECLARE(char *) switch_core_session_url_encode_opt(switch_core_session_t *session, const char *url, switch_bool_t double_encode);
1243 SWITCH_DECLARE(char *) switch_core_session_url_encode(switch_core_session_t *session, const char *url);
1244 
1245 
1247  const char *from,
1248  const char *headers,
1249  const char *body, const char *file, const char *convert_cmd, const char *convert_ext);
1250 SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char close);
1251 
1252 static inline void switch_separate_file_params(const char *file, char **file_portion, char **params_portion)
1253 {
1254  char *e = NULL;
1255  char *space = strdup(file);
1256 
1257  switch_assert(space);
1258  file = space;
1259 
1260  *file_portion = NULL;
1261  *params_portion = NULL;
1262 
1263  while (*file == '{') {
1264  e = switch_find_end_paren(file, '{', '}');
1265  file = e + 1;
1266  while(*file == ' ') file++;
1267  }
1268 
1269 
1270  if (e) {
1271  *file_portion = strdup((char *)file);
1272  *++e = '\0';
1273  *params_portion = (char *)space;
1274  } else {
1275  *file_portion = (char *)space;
1276  }
1277 
1278  return;
1279 }
1280 
1281 static inline switch_bool_t switch_is_file_path(const char *file)
1282 {
1283  const char *e;
1284  int r;
1285 
1286  if (zstr(file)) {
1287  return SWITCH_FALSE;
1288  }
1289 
1290  while(*file == '{') {
1291  if ((e = switch_find_end_paren(file, '{', '}'))) {
1292  file = e + 1;
1293  while(*file == ' ') file++;
1294  }
1295  }
1296 
1297 #ifdef WIN32
1298  r = (*file == '\\' || *(file + 1) == ':' || *file == '/' || strstr(file, SWITCH_URL_SEPARATOR));
1299 #else
1300  r = ((*file == '/') || strstr(file, SWITCH_URL_SEPARATOR));
1301 #endif
1302 
1303  return r ? SWITCH_TRUE : SWITCH_FALSE;
1304 }
1305 
1306 static inline int switch_filecmp(const char *a, const char *b)
1307 {
1308  const char *e;
1309 
1310  if (zstr(a) || zstr(b)) {
1311  return -1;
1312  }
1313 
1314  while(*a == '{') {
1315  if ((e = switch_find_end_paren(a, '{', '}'))) {
1316  a = e + 1;
1317  while(*a == ' ') a++;
1318  }
1319  }
1320 
1321  while(*b == '{') {
1322  if ((e = switch_find_end_paren(b, '{', '}'))) {
1323  b = e + 1;
1324  while(*b == ' ') b++;
1325  }
1326  }
1327 
1328  return strcmp(a, b);
1329 }
1330 
1331 
1332 static inline const char *switch_parse_audio_col(switch_audio_col_t col)
1333 {
1334  const char *field = NULL;
1335 
1336  switch (col) {
1338  field = "title";
1339  break;
1341  field = "comment";
1342  break;
1344  field = "artist";
1345  break;
1347  field = "date";
1348  break;
1350  field = "software";
1351  break;
1353  field = "copyright";
1354  break;
1355  default:
1356  break;
1357  }
1358 
1359  return field;
1360 }
1361 
1362 SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, uint32_t *bitp);
1364  switch_memory_pool_t *pool);
1365 SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token);
1366 #define switch_network_list_add_cidr(_list, _cidr_str, _ok) switch_network_list_add_cidr_token(_list, _cidr_str, _ok, NULL)
1367 
1368 SWITCH_DECLARE(char *) switch_network_ipv4_mapped_ipv6_addr(const char* ip_str);
1369 SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok);
1370 
1373 
1378 #define switch_network_list_validate_ip(_list, _ip) switch_network_list_validate_ip_token(_list, _ip, NULL);
1379 
1380 #define switch_test_subnet(_ip, _net, _mask) (_mask ? ((_net & _mask) == (_ip & _mask)) : _net ? _net == _ip : 1)
1381 
1382 SWITCH_DECLARE(int) switch_inet_pton(int af, const char *src, void *dst);
1383 
1384 SWITCH_DECLARE(const char *) switch_dow_int2str(int val);
1385 SWITCH_DECLARE(int) switch_dow_str2int(const char *exp);
1386 SWITCH_DECLARE(switch_bool_t) switch_dow_cmp(const char *exp, int val);
1387 SWITCH_DECLARE(int) switch_number_cmp(const char *exp, int val);
1388 SWITCH_DECLARE(int) switch_tod_cmp(const char *exp, int val);
1389 
1390 SWITCH_DECLARE(int) switch_fulldate_cmp(const char *exp, switch_time_t *ts);
1391 SWITCH_DECLARE(void) switch_split_date(const char *exp, int *year, int *month, int *day);
1392 SWITCH_DECLARE(void) switch_split_time(const char *exp, int *hour, int *min, int *sec);
1393 
1394 /*!
1395  \brief Split a user@domain string as user and domain
1396  \param in the input string
1397  \param user the string to put the user into
1398  \param domain the string to put the domain into
1399  \return 1 if successfull
1400  \note Extended formats protocol:user@domain:port (Example: sip:toto@example.org)
1401 */
1402 SWITCH_DECLARE(int) switch_split_user_domain(char *in, char **user, char **domain);
1403 
1404 SWITCH_DECLARE(void *) switch_calloc(size_t nmemb, size_t size);
1405 
1406 #ifdef __clang_analyzer__
1407 #define calloc switch_calloc
1408 #endif
1409 
1410 /* malloc or DIE macros */
1411 #ifdef NDEBUG
1412 #define switch_malloc(ptr, len) (void)( (!!(ptr = malloc(len))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr )
1413 #define switch_zmalloc(ptr, len) (void)( (!!(ptr = calloc(1, (len)))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
1414 #if (_MSC_VER >= 1500) // VC9+
1415 #define switch_strdup(ptr, s) (void)( (!!(ptr = _strdup(s))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
1416 #else
1417 #define switch_strdup(ptr, s) (void)( (!!(ptr = strdup(s))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
1418 #endif
1419 #else
1420 #if (_MSC_VER >= 1500) // VC9+
1421 #define switch_malloc(ptr, len) (void)(assert(((ptr) = malloc((len)))),ptr);__analysis_assume( ptr )
1422 #define switch_zmalloc(ptr, len) (void)(assert((ptr = calloc(1, (len)))),ptr);__analysis_assume( ptr )
1423 #define switch_strdup(ptr, s) (void)(assert(((ptr) = _strdup(s))),ptr);__analysis_assume( ptr )
1424 #else
1425 #define switch_malloc(ptr, len) (void)(switch_assert(((ptr) = malloc((len)))),ptr)
1426 #define switch_zmalloc(ptr, len) (void)(switch_assert((ptr = calloc(1, (len)))),ptr)
1427 #define switch_strdup(ptr, s) (void)(switch_assert(((ptr) = strdup((s)))),ptr)
1428 #endif
1429 #endif
1430 
1431 #define DUMP_EVENT(_e) {char *event_str;switch_event_serialize(_e, &event_str, SWITCH_FALSE);switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "DUMP\n%s\n", event_str);free(event_str);}
1432 
1433 #ifndef _MSC_VER
1434 #define switch_inet_ntop inet_ntop
1435 #else
1436 SWITCH_DECLARE(const char *) switch_inet_ntop(int af, void const *src, char *dst, size_t size);
1437 #endif
1438 
1439 SWITCH_DECLARE(char *) switch_uuid_str(char *buf, switch_size_t len);
1440 SWITCH_DECLARE(char *) switch_format_number(const char *num);
1441 
1442 SWITCH_DECLARE(unsigned int) switch_atoui(const char *nptr);
1443 SWITCH_DECLARE(unsigned long) switch_atoul(const char *nptr);
1444 
1445 /**
1446  * Portable version of strerror_r(), work around for the incompatible
1447  * return type of GNU and XSI variants.
1448  * \param[in] errnum Error number
1449  * \param[both] buf Buffer for error message
1450  * \param[in] buflen Size of message buffer
1451  * \return Pointer to message buffer, returning error message or "Unknown error xxx" if none found
1452  */
1453 SWITCH_DECLARE(char *) switch_strerror_r(int errnum, char *buf, switch_size_t buflen);
1454 SWITCH_DECLARE(int) switch_wait_sock(switch_os_socket_t sock, uint32_t ms, switch_poll_t flags);
1455 SWITCH_DECLARE(int) switch_wait_socklist(switch_waitlist_t *waitlist, uint32_t len, uint32_t ms);
1456 
1457 typedef struct switch_http_request_s {
1458  const char *method; /* GET POST PUT DELETE OPTIONS PATCH HEAD */
1459  const char *uri;
1460  const char *qs; /* query string*/
1461  const char *host;
1463  const char *from;
1464  const char *user_agent;
1465  const char *referer;
1466  const char *user;
1468  const char *content_type;
1474  void *user_data; /* private user data */
1475 
1476  /* private members used by the parser internally */
1477  char *_buffer;
1480 
1481 /**
1482  * parse http headers in a buffer
1483  * return status of success or not
1484  * \param[in] buffer the buffer start from the very begining of the http request, e.g. 'GET '
1485  * \param[in] datalen the buffer length
1486  * \param[out] the http request pointer or null, need destroy later if got non-NULL pointer
1487  * \return SWITCH_STATUS_SUCCESS | SWITCH_STATUS_FALSE
1488  */
1492 /**
1493  * parse http query string
1494  * \param[in] request the http request object
1495  * \param[in] qs the query string buffer
1496  *
1497  * qs buffer will be modified, so be sure to dup the qs before passing into this function if you want to keep the original string untouched
1498  * if qs is NULL, the it will parse request->qs, request->qs will be duplicated before parse to avoid being modified
1499  */
1500 
1502 
1512 
1513 typedef struct {
1514  int64_t userms;
1515  int64_t kernelms;
1516 } switch_cputime;
1517 /**
1518 / Return used CPU time in this process for user and kernel code
1519 **/
1521 
1522 SWITCH_DECLARE(char *)switch_html_strip(const char *str);
1523 
1524 SWITCH_DECLARE(unsigned long) switch_getpid(void);
1525 
1526 SWITCH_DECLARE(switch_status_t) switch_digest(const char *digest_name, unsigned char **digest, const void *input, switch_size_t inputLen, unsigned int *outputlen);
1527 SWITCH_DECLARE(switch_status_t) switch_digest_string(const char *digest_name, char **digest_str, const void *input, switch_size_t inputLen, unsigned int *outputlen);
1528 /**
1529  * \param[in] secret the secret string
1530  * \param[in] token the jwt token, only alg: HS256 is supported
1531  *
1532  * \return NULL or payload in cJSON
1533 **/
1534 SWITCH_DECLARE(cJSON *) switch_jwt_verify(const char *secret, const char *token);
1535 
1536 /**
1537  * \param[in] secret the secret string
1538  * \param[in] payload the payload
1539  * \param[in] size the payload size
1540  *
1541  * \return NULL or signed token
1542 **/
1543 SWITCH_DECLARE(char *) switch_jwt_sign(const char *secret, const uint8_t *payload, switch_size_t size);
1544 
1545 SWITCH_DECLARE(char *) switch_must_strdup(const char *_s);
1547 
1549 #endif
1550 /* For Emacs:
1551  * Local Variables:
1552  * mode:c
1553  * indent-tabs-mode:t
1554  * tab-width:4
1555  * c-basic-offset:4
1556  * End:
1557  * For VIM:
1558  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
1559  */
static void switch_tolower_max(char *s)
Definition: switch_utils.h:231
int switch_isdigit(int c)
#define switch_inet_ntop
unsigned int switch_atoui(const char *nptr)
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
const char * switch_priority_name(switch_priority_t priority)
Return a printable name of a switch_priority_t.
int switch_isspace(int c)
int switch_islower(int c)
switch_status_t switch_frame_buffer_free(switch_frame_buffer_t *fb, switch_frame_t **frameP)
Definition: switch_utils.c:217
const char *const const double number
Definition: switch_cJSON.h:254
char * switch_find_end_paren(const char *s, char open, char close)
Definition: switch_utils.c:796
static void switch_toupper_max(char *s)
Definition: switch_utils.h:203
static char * switch_sanitize_number(char *number)
Definition: switch_utils.h:737
int switch_wait_sock(switch_os_socket_t sock, uint32_t ms, switch_poll_t flags)
static char * switch_get_hex_bytes(switch_byte_t *buf, switch_size_t datalen, char *new_buf, switch_size_t new_datalen)
Definition: switch_utils.h:60
char * switch_strip_nonnumerics(char *in, char *out, switch_size_t len)
switch_size_t bytes_read
int switch_frame_buffer_size(switch_frame_buffer_t *fb)
Definition: switch_utils.c:287
switch_status_t switch_frame_buffer_trypush(switch_frame_buffer_t *fb, void *ptr)
Definition: switch_utils.c:272
switch_status_t switch_network_list_create(switch_network_list_t **list, const char *name, switch_bool_t default_type, switch_memory_pool_t *pool)
Definition: switch_utils.c:459
#define SWITCH_END_EXTERN_C
Definition: switch.h:43
char * switch_core_url_encode_opt(switch_memory_pool_t *pool, const char *url, switch_bool_t double_encode)
int switch_iscntrl(int c)
switch_status_t switch_network_list_add_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token)
Definition: switch_utils.c:702
switch_size_t switch_b64_decode(const char *in, char *out, switch_size_t olen)
static int switch_errno_is_break(int errcode)
Definition: switch_utils.h:649
static void switch_separate_file_params(const char *file, char **file_portion, char **params_portion)
static char * switch_var_clean_string(char *s)
Definition: switch_utils.h:807
switch_status_t switch_frame_buffer_trypop(switch_frame_buffer_t *fb, void **ptr)
Definition: switch_utils.c:282
static int switch_string_has_escaped_data(const char *in)
Definition: switch_utils.h:384
switch_uri_flags
flags to be used with switch_build_uri()
Definition: switch_utils.h:615
unsigned int switch_separate_string_string(char *buf, char *delim, _Post_count_(return) char **array, unsigned int arraylen)
int get_addr_int(switch_sockaddr_t *sa)
static long int switch_safe_atol(const char *nptr, long int dft)
Turn a string into a long integer (default if NULL)
Definition: switch_utils.h:863
int switch_build_uri(char *uri, switch_size_t size, const char *scheme, const char *user, const switch_sockaddr_t *sa, int flags)
build a URI string from components
cJSON *const to
switch_bool_t switch_is_leading_number(const char *str)
switch_bool_t
Definition: switch_types.h:437
int switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, uint32_t *bitp)
Definition: switch_utils.c:743
switch_status_t switch_frame_alloc(switch_frame_t **frame, switch_size_t size)
Definition: switch_utils.c:109
switch_audio_col_t
Definition: switch_types.h:613
#define SWITCH_URL_SEPARATOR
Definition: switch_types.h:126
const cJSON *const b
Definition: switch_cJSON.h:243
switch_priority_t
Priority Indication.
switch_bool_t switch_is_uint_in_range(const char *str, unsigned int from, unsigned int to)
Check if a 32 bit unsigned number is in a range.
switch_memory_pool_t * pool
void switch_http_dump_request(switch_http_request_t *request)
Representation of an event.
Definition: switch_event.h:80
char * switch_amp_encode(char *s, char *buf, switch_size_t len)
Definition: switch_utils.c:939
switch_status_t switch_frame_free(switch_frame_t **frame)
Definition: switch_utils.c:363
char * switch_format_number(const char *num)
switch_status_t switch_network_list_add_host_port_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok, switch_network_port_range_p port)
Definition: switch_utils.c:707
int old_switch_toupper(int c)
char * switch_util_quote_shell_arg_pool(const char *string, switch_memory_pool_t *pool)
Quote shell argument, allocating from pool if provided.
switch_bool_t switch_network_list_validate_ip6_port_token(switch_network_list_t *list, ip_t ip, int port, const char **token)
Definition: switch_utils.c:497
switch_status_t switch_http_parse_header(char *buffer, uint32_t datalen, switch_http_request_t *request)
char * switch_find_parameter(const char *str, const char *param, switch_memory_pool_t *pool)
Definition: switch_utils.c:415
char * switch_print_host(switch_sockaddr_t *addr, char *buf, switch_size_t len)
Definition: switch_utils.c:98
switch_bool_t switch_is_number(const char *str)
char * switch_strip_whitespace(const char *str)
switch_bool_t switch_network_list_validate_ip6_token(switch_network_list_t *list, ip_t ip, const char **token)
Definition: switch_utils.c:572
switch_size_t switch_fd_read_line(int fd, char *buf, switch_size_t len)
Definition: switch_utils.c:822
uint32_t switch_core_cpu_count(void)
Definition: switch_core.c:1055
int switch_isgraph(int c)
void switch_split_date(const char *exp, int *year, int *month, int *day)
char * switch_url_encode(const char *url, char *buf, size_t len)
static int32_t switch_calc_bitrate(int w, int h, float quality, double fps)
static void switch_calc_fps(switch_fps_t *fpsP, float fps, int samplerate)
int switch_strcasecmp_any(const char *str,...)
Definition: switch_utils.c:394
switch_status_t switch_frame_buffer_dup(switch_frame_buffer_t *fb, switch_frame_t *orig, switch_frame_t **clone)
Definition: switch_utils.c:250
static int32_t switch_parse_bandwidth_string(const char *bwv)
switch_bool_t switch_is_lan_addr(const char *ip)
const char * content_type
switch_status_t switch_frame_buffer_destroy(switch_frame_buffer_t **fbP)
Definition: switch_utils.c:292
unsigned int switch_separate_string_cheap(_In_ const char *buf, char delim, _Post_count_(return) const char **array, _Post_count_(return) unsigned int larray[], unsigned int arraylen)
Separate a string into an array based on a character delimiter, no memory corruption! DOESN&#39;T support...
#define SWITCH_URL_UNSAFE
Definition: switch_utils.h:47
static uint32_t switch_known_bitrate(switch_payload_t payload)
Definition: switch_utils.h:479
static uint32_t switch_parse_cpu_string(const char *cpu)
uint8_t switch_byte_t
Definition: switch_types.h:256
const char * user_agent
switch_bool_t _destroy_headers
#define end_of_p(_s)
Definition: switch_utils.h:686
#define zstr(x)
Definition: switch_utils.h:314
static int switch_safe_atoi(const char *nptr, int dft)
Turn a string into an integer (default if NULL)
Definition: switch_utils.h:851
static char * switch_strchr_strict(const char *in, char find, const char *allowed)
Definition: switch_utils.h:334
switch_status_t switch_resolve_host(const char *host, char *buf, size_t buflen)
switch_bool_t switch_network_list_validate_ip_token(switch_network_list_t *list, uint32_t ip, const char **token)
Definition: switch_utils.c:577
static char * switch_safe_strdup(const char *it)
Definition: switch_utils.h:887
switch_bool_t switch_dow_cmp(const char *exp, int val)
const char * switch_memory_usage_stream(switch_stream_handle_t *stream)
char * switch_jwt_sign(const char *secret, const uint8_t *payload, switch_size_t size)
void switch_getcputime(switch_cputime *t)
int64_t switch_time_t
Definition: switch_apr.h:188
switch_status_t switch_network_list_add_host_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok)
Definition: switch_utils.c:737
switch_byte_t switch_byte_t * buf
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
static switch_bool_t switch_strstr(char *s, char *q)
Test if one string is inside another with extra case checking.
Definition: switch_utils.h:937
switch_byte_t in
static switch_bool_t switch_string_var_check(char *s, switch_bool_t disable)
Definition: switch_utils.h:763
switch_bool_t switch_testv6_subnet(ip_t _ip, ip_t _net, ip_t _mask)
Definition: switch_utils.c:483
int ports[MAX_NETWORK_PORTS]
Definition: switch_utils.h:53
static switch_bool_t switch_is_moh(const char *s)
Definition: switch_utils.h:319
unsigned short get_port(struct sockaddr *sa)
get the port number of an ip address
int switch_cmp_addr(switch_sockaddr_t *sa1, switch_sockaddr_t *sa2, switch_bool_t ip_only)
int switch_split_user_domain(char *in, char **user, char **domain)
Split a user string as user and domain.
switch_status_t switch_b64_encode(unsigned char *in, switch_size_t ilen, unsigned char *out, switch_size_t olen)
uint32_t v4
Definition: switch_utils.h:278
int old_switch_tolower(int c)
#define _Out_opt_bytecapcount_(x)
int switch_isxdigit(int c)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
static uint32_t switch_toupper(uint32_t eax)
Definition: switch_utils.h:101
int switch_isprint(int c)
unsigned long switch_atoul(const char *nptr)
int switch_os_socket_t
#define _In_opt_
char * switch_network_ipv4_mapped_ipv6_addr(const char *ip_str)
Definition: switch_utils.c:582
char * switch_escape_string(const char *in, char *out, switch_size_t outlen)
char * switch_strip_commas(char *in, char *out, switch_size_t len)
char * switch_strerror_r(int errnum, char *buf, switch_size_t buflen)
An abstraction of a data frame.
Definition: switch_frame.h:54
uintptr_t switch_size_t
uint16_t switch_port_t
switch_size_t switch_fp_read_dline(FILE *fd, char **buf, switch_size_t *len)
Definition: switch_utils.c:892
int switch_socket_waitfor(switch_pollfd_t *poll, int ms)
Wait for a socket.
static switch_bool_t switch_string_var_check_const(const char *s)
Definition: switch_utils.h:788
switch_byte_t switch_byte_t uint32_t buflen
struct switch_http_request_s switch_http_request_t
char * switch_url_decode(char *s)
char switch_rfc2833_to_char(int event)
Return the RFC2833 character based on an event id.
int switch_inet_pton(int af, const char *src, void *dst)
Definition: inet_pton.c:74
void switch_split_time(const char *exp, int *hour, int *min, int *sec)
char * switch_replace_char(char *str, char from, char to, switch_bool_t dup)
int switch_isalpha(int c)
char * switch_must_strdup(const char *_s)
void switch_http_free_request(switch_http_request_t *request)
#define MAX_NETWORK_PORTS
Definition: switch_utils.h:49
char * switch_util_quote_shell_arg(const char *string)
Quote shell argument.
static char * switch_clean_string(char *s)
Definition: switch_utils.h:813
#define _Post_count_(x)
char * switch_core_session_url_encode_opt(switch_core_session_t *session, const char *url, switch_bool_t double_encode)
int switch_ispunct(int c)
unsigned char switch_char_to_rfc2833(char key)
Return the RFC2833 event based on an key character.
struct fspr_sockaddr_t switch_sockaddr_t
Definition: switch_apr.h:1029
char * switch_url_encode_opt(const char *url, char *buf, size_t len, switch_bool_t double_encode)
char * switch_pool_strip_whitespace(switch_memory_pool_t *pool, const char *str)
static char switch_itodtmf(char i)
Definition: switch_utils.h:450
char * switch_core_url_encode(switch_memory_pool_t *pool, const char *url)
#define _Check_return_
static _Check_return_ int _zstr(_In_opt_z_ const char *s)
Test for NULL or zero length string.
Definition: switch_utils.h:305
char * ip
Definition: switch_msrp.c:60
char * switch_separate_paren_args(char *str)
const char * switch_dow_int2str(int val)
switch_status_t switch_frame_buffer_push(switch_frame_buffer_t *fb, void *ptr)
Definition: switch_utils.c:267
switch_status_t switch_network_list_add_cidr_port_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token, switch_network_port_range_p port)
Definition: switch_utils.c:675
static char * switch_lc_strdup(const char *it)
Definition: switch_utils.h:900
switch_size_t content_length
static int switch_filecmp(const char *a, const char *b)
static char * switch_uc_strdup(const char *it)
Definition: switch_utils.h:914
switch_status_t
Common return values.
char * switch_string_replace(const char *string, const char *search, const char *replace)
char * switch_uuid_str(char *buf, switch_size_t len)
int switch_tod_cmp(const char *exp, int val)
static int switch_needs_url_encode(const char *s)
switch_status_t switch_frame_buffer_create(switch_frame_buffer_t **fbP, switch_size_t qlen)
Definition: switch_utils.c:303
char * get_addr(char *buf, switch_size_t len, struct sockaddr *sa, socklen_t salen)
find the char representation of an ip adress
switch_status_t switch_string_match(const char *string, size_t string_len, const char *search, size_t search_len)
Main Library Header.
static switch_bool_t switch_is_file_path(const char *file)
int switch_dow_str2int(const char *exp)
#define SWITCH_DECLARE(type)
switch_bool_t switch_simple_email(const char *to, const char *from, const char *headers, const char *body, const char *file, const char *convert_cmd, const char *convert_ext)
switch_bool_t switch_network_list_validate_ip_port_token(switch_network_list_t *list, uint32_t ip, int port, const char **token)
Definition: switch_utils.c:546
unsigned long switch_getpid(void)
switch_status_t switch_frame_buffer_pop(switch_frame_buffer_t *fb, void **ptr)
Definition: switch_utils.c:277
switch_status_t switch_frame_dup(switch_frame_t *orig, switch_frame_t **clone)
Definition: switch_utils.c:321
char * switch_escape_char(switch_memory_pool_t *pool, char *in, const char *delim, char esc)
Escape a string by prefixing a list of characters with an escape character.
char * switch_html_strip(const char *str)
int switch_number_cmp(const char *exp, int val)
switch_status_t switch_digest_string(const char *digest_name, char **digest_str, const void *input, switch_size_t inputLen, unsigned int *outputlen)
void * switch_calloc(size_t nmemb, size_t size)
Definition: switch_utils.c:86
switch_status_t switch_digest(const char *digest_name, unsigned char **digest, const void *input, switch_size_t inputLen, unsigned int *outputlen)
char * buffer
Definition: switch_cJSON.h:153
void switch_http_parse_qs(switch_http_request_t *request, char *qs)
char * get_addr6(char *buf, switch_size_t len, struct sockaddr_in6 *sa, socklen_t salen)
char * key
Definition: switch_msrp.c:64
static int switch_dtmftoi(char *s)
Definition: switch_utils.h:463
int switch_isalnum(int c)
const char * switch_stristr(const char *instr, const char *str)
static switch_bool_t switch_is_digit_string(const char *s)
Definition: switch_utils.h:437
switch_status_t switch_find_local_ip(_Out_opt_bytecapcount_(len) char *buf, _In_ int len, _In_opt_ int *mask, _In_ int family)
find local ip of the box
#define _In_opt_z_
static int switch_false(const char *expr)
Evaluate the falsefullness of a string expression.
Definition: switch_utils.h:551
struct fspr_pool_t switch_memory_pool_t
const char *const name
Definition: switch_cJSON.h:250
switch_status_t switch_find_interface_ip(_Out_opt_bytecapcount_(len) char *buf, _In_ int len, _In_opt_ int *mask, _In_ const char *ifname, _In_ int family)
find primary ip of the specified interface
static long long int switch_safe_atoll(const char *nptr, long long int dft)
Turn a string into a long long integer (default if NULL)
Definition: switch_utils.h:875
switch_size_t switch_fd_read_dline(int fd, char **buf, switch_size_t *len)
Definition: switch_utils.c:844
switch_bool_t keepalive
cJSON * switch_jwt_verify(const char *secret, const char *token)
switch_poll_t
static uint32_t switch_round_to_step(uint32_t num, uint32_t step)
Definition: switch_utils.h:81
#define switch_assert(expr)
const char * switch_cut_path(const char *in)
Create a pointer to the file name in a given file path eliminating the directory name.
static uint32_t switch_tolower(uint32_t eax)
Definition: switch_utils.h:112
switch_bool_t switch_ast2regex(const char *pat, char *rbuf, size_t len)
char * switch_strip_spaces(char *str, switch_bool_t dup)
switch_network_port_range_t * switch_network_port_range_p
Definition: switch_utils.h:58
static const char * switch_parse_audio_col(switch_audio_col_t col)
switch_event_t * headers
switch_time_t switch_str_time(const char *in)
Converts a string representation of a date into a switch_time_t.
static char * switch_clean_name_string(char *s)
Definition: switch_utils.h:827
char * switch_core_session_url_encode(switch_core_session_t *session, const char *url)
int switch_fulldate_cmp(const char *exp, switch_time_t *ts)
switch_size_t bytes_header
static switch_byte_t switch_true_byte(const char *expr)
Definition: switch_utils.h:531
int switch_isupper(int c)
switch_size_t bytes_buffered
int switch_cp_addr(switch_sockaddr_t *sa1, switch_sockaddr_t *sa2)
uint8_t switch_payload_t
char * switch_escape_string_pool(const char *in, switch_memory_pool_t *pool)
static char * switch_print_bits(const unsigned char *byte, char *buf, switch_size_t buflen)
Definition: switch_utils.h:412
#define _In_
int switch_wait_socklist(switch_waitlist_t *waitlist, uint32_t len, uint32_t ms)
#define SWITCH_BEGIN_EXTERN_C
Definition: switch.h:42