Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Functions | Variables
utils.c File Reference

Utility functions. More...

#include "asterisk.h"
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>
#include "asterisk/network.h"
#include "asterisk/ast_version.h"
#include "asterisk/lock.h"
#include "asterisk/io.h"
#include "asterisk/md5.h"
#include "asterisk/sha1.h"
#include "asterisk/cli.h"
#include "asterisk/linkedlists.h"
#include "asterisk/astobj2.h"
#include "asterisk/strings.h"
#include "asterisk/time.h"
#include "asterisk/utils.h"
#include "asterisk/threadstorage.h"
#include "asterisk/config.h"
#include "asterisk/alertpipe.h"

Go to the source code of this file.

Data Structures

struct  baseio
 Structure used for base64 encoding. More...
 
struct  thr_arg
 

Macros

#define AST_API_MODULE   /* ensure that inlinable API functions will be built in lock.h if required */
 
#define AST_API_MODULE   /* ensure that inlinable API functions will be built in this module if required */
 
#define AST_API_MODULE   /* ensure that inlinable API functions will be built in this module if required */
 
#define AST_API_MODULE   /* ensure that inlinable API functions will be built in this module if required */
 
#define AST_API_MODULE
 
#define AST_API_MODULE
 
#define AST_API_MODULE
 
#define BASELINELEN   72
 
#define BASEMAXINLINE   256
 
#define ONE_MILLION   1000000
 

Functions

void DO_CRASH_NORETURN __ast_assert_failed (int condition, const char *condition_str, const char *file, int line, const char *function)
 
int __ast_fd_set_flags (int fd, int flags, enum ast_fd_flag_operation op, const char *file, int lineno, const char *function)
 
static void __init_inet_ntoa_buf (void)
 
static void __init_thread_user_interface_tl (void)
 A thread local indicating whether the current thread is a user interface.
 
int ast_background_stacksize (void)
 
int ast_base64_encode_file (FILE *inputfile, FILE *outputfile, const char *endl)
 Performs a base 64 encode algorithm on the contents of a File. More...
 
int ast_base64_encode_file_path (const char *filename, FILE *outputfile, const char *endl)
 Performs a base 64 encode algorithm on the contents of a File. More...
 
int ast_base64decode (unsigned char *dst, const char *src, int max)
 decode BASE64 encoded text More...
 
char * ast_base64decode_string (const char *src)
 Decode BASE64 encoded text and return the string. More...
 
int ast_base64encode (char *dst, const unsigned char *src, int srclen, int max)
 Encode data in base64. More...
 
int ast_base64encode_full (char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
 encode text to BASE64 coding
 
char * ast_base64encode_string (const char *src)
 Encode to BASE64 and return encoded string. More...
 
int ast_base64url_decode (unsigned char *dst, const char *src, int max)
 Decode data from base64 URL. More...
 
char * ast_base64url_decode_string (const char *src)
 Decode string from base64 URL. More...
 
int ast_base64url_encode (char *dst, const unsigned char *src, int srclen, int max)
 Encode data in base64 URL. More...
 
int ast_base64url_encode_full (char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
 Same as ast_base64encode_full but for base64 URL. More...
 
char * ast_base64url_encode_string (const char *src)
 Encode string in base64 URL. More...
 
int ast_build_string (char **buffer, size_t *space, const char *fmt,...)
 Build a string in a buffer, designed to be called repeatedly. More...
 
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. More...
 
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. More...
 
int ast_check_command_in_path (const char *cmd)
 Test for the presence of an executable command in $PATH. More...
 
int ast_check_ipv6 (void)
 Test that an OS supports IPv6 Networking. More...
 
int ast_compare_versions (const char *version1, const char *version2)
 Compare 2 major.minor.patch.extra version strings. More...
 
void DO_CRASH_NORETURN ast_do_crash (void)
 Force a crash if DO_CRASH is defined. More...
 
int ast_eid_cmp (const struct ast_eid *eid1, const struct ast_eid *eid2)
 Compare two EIDs. More...
 
int ast_eid_is_empty (const struct ast_eid *eid)
 Check if EID is empty. More...
 
char * ast_eid_to_str (char *s, int maxlen, struct ast_eid *eid)
 Convert an EID to a string. More...
 
void ast_enable_packet_fragmentation (int sock)
 Disable PMTU discovery on a socket. More...
 
char * ast_escape (char *dest, const char *s, size_t size, const char *to_escape)
 Escape the 'to_escape' characters in the given string. More...
 
char * ast_escape_alloc (const char *s, const char *to_escape)
 Escape the 'to_escape' characters in the given string. More...
 
char * ast_escape_c (char *dest, const char *s, size_t size)
 Escape standard 'C' sequences in the given string. More...
 
char * ast_escape_c_alloc (const char *s)
 Escape standard 'C' sequences in the given string. More...
 
char * ast_escape_quoted (const char *string, char *outbuf, int buflen)
 Escape characters found in a quoted string. More...
 
char * ast_escape_semicolons (const char *string, char *outbuf, int buflen)
 Escape semicolons found in a string. More...
 
int ast_false (const char *s)
 Make sure something is false. Determine if a string containing a boolean value is "false". This function checks to see whether a string passed to it is an indication of an "false" value. It checks to see if the string is "no", "false", "n", "f", "off" or "0". More...
 
int ast_file_is_readable (const char *filename)
 Test that a file exists and is readable by the effective user. More...
 
void ast_format_duration_hh_mm_ss (int duration, char *buf, size_t length)
 Formats a duration into HH:MM:SS. More...
 
int ast_get_tid (void)
 Get current thread ID. More...
 
int ast_get_time_t (const char *src, time_t *dst, time_t _default, int *consumed)
 get values from config variables. More...
 
int ast_get_timeval (const char *src, struct timeval *dst, struct timeval _default, int *consumed)
 get values from config variables. More...
 
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 not thread safe) More...
 
const char * ast_inet_ntoa (struct in_addr ia)
 ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa More...
 
void ast_join_delim (char *s, size_t len, const char *const w[], unsigned int size, char delim)
 Join an array of strings into a single string. More...
 
void ast_md5_hash (char *output, const char *input)
 Produce 32 char MD5 hash of value. More...
 
int ast_mkdir (const char *path, int mode)
 Recursively create directory path. More...
 
int ast_parse_digest (const char *digest, struct ast_http_digest *d, int request, int pedantic)
 Parse digest authorization header. More...
 
char * ast_process_quotes_and_slashes (char *start, char find, char replace_with)
 Process a string to find and replace characters. More...
 
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)
 
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)
 
long int ast_random (void)
 
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". More...
 
int ast_remaining_ms (struct timeval start, int max_ms)
 Calculate remaining milliseconds given a starting timestamp and upper bound. More...
 
void ast_replace_subargument_delimiter (char *s)
 Replace '^' in a string with ','. More...
 
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. More...
 
void ast_set_default_eid (struct ast_eid *eid)
 Fill in an ast_eid with the default eid of this machine. More...
 
void ast_sha1_hash (char *output, const char *input)
 Produce 40 char SHA1 hash of value. More...
 
void ast_sha1_hash_uint (uint8_t *digest, const char *input)
 Produce a 20 byte SHA1 hash of value. More...
 
int ast_str_to_eid (struct ast_eid *eid, const char *s)
 Convert a string into an EID. More...
 
char * ast_strip_quoted (char *s, const char *beg_quotes, const char *end_quotes)
 Strip leading/trailing whitespace and quotes from a string. More...
 
char * ast_strsep (char **iss, const char sep, uint32_t flags)
 Act like strsep but ignore separators inside quotes. More...
 
char * ast_strsep_quoted (char **iss, const char sep, const char quote, uint32_t flags)
 Like ast_strsep() except you can specify a specific quote character. More...
 
int ast_thread_is_user_interface (void)
 Indicates whether the current thread is a user interface. More...
 
int ast_thread_user_interface_set (int is_user_interface)
 Set the current thread's user interface status. More...
 
char * ast_to_camel_case_delim (const char *s, const char *delim)
 Attempts to convert the given string to camel case using the specified delimiter. More...
 
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". More...
 
struct timeval ast_tvadd (struct timeval a, struct timeval b)
 Returns the sum of two timevals a + b.
 
struct timeval ast_tvsub (struct timeval a, struct timeval b)
 Returns the difference of two timevals a - b.
 
char * ast_unescape_c (char *src)
 Convert some C escape sequences. More...
 
void ast_unescape_quoted (char *quote_str)
 Unescape quotes in a string. More...
 
char * ast_unescape_semicolon (char *s)
 Strip backslash for "escaped" semicolons, the string to be stripped (will be modified). More...
 
void ast_uri_decode (char *s, struct ast_flags spec)
 Decode URI, URN, URL (overwrite string) More...
 
char * ast_uri_encode (const char *string, char *outbuf, int buflen, struct ast_flags spec)
 Turn text string to URI-encoded XX version. More...
 
int ast_utils_init (void)
 
char * ast_utils_which (const char *binary, char *fullpath, size_t fullpath_size)
 Resolve a binary to a full pathname. More...
 
int ast_wait_for_input (int fd, int ms)
 
int ast_wait_for_output (int fd, int ms)
 
int ast_xml_escape (const char *string, char *const outbuf, const size_t buflen)
 Escape reserved characters for use in XML. More...
 
static void base64_init (void)
 
static void * dummy_start (void *data)
 
static char * escape_alloc (const char *s, size_t *size)
 
static int inbuf (struct baseio *bio, FILE *fi)
 utility used by inchar(), for base_encode()
 
static int inchar (struct baseio *bio, FILE *fi)
 utility used by base_encode()
 
static int ochar (struct baseio *bio, int c, FILE *so, const char *endl)
 utility used by base_encode()
 
static int safe_mkdir (const char *base_path, char *path, int mode)
 
static struct timeval tvfix (struct timeval a)
 
static void utils_shutdown (void)
 
static int wait_for_output (int fd, int timeoutms)
 

Variables

const struct ast_flags ast_uri_http = {AST_URI_UNRESERVED}
 
const struct ast_flags ast_uri_http_legacy = {AST_URI_LEGACY_SPACE | AST_URI_UNRESERVED}
 
const struct ast_flags ast_uri_sip_user = {AST_URI_UNRESERVED | AST_URI_SIP_USER_UNRESERVED}
 
static char b2a [256]
 
static char b2a_url [256]
 
static char base64 [64]
 
static char base64url [64]
 
static int dev_urandom_fd = -1
 
char escape_sequences []
 
static char escape_sequences_map []
 
static struct ast_threadstorage inet_ntoa_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_inet_ntoa_buf , .custom_init = NULL , }
 
static ast_mutex_t randomlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static struct ast_threadstorage thread_user_interface_tl = { .once = PTHREAD_ONCE_INIT , .key_init = __init_thread_user_interface_tl , .custom_init = NULL , }
 

Detailed Description

Utility functions.

Note
These are important for portability and security, so please use them in favour of other routines. Please consult the CODING GUIDELINES for more information.

Definition in file utils.c.

Macro Definition Documentation

#define BASELINELEN   72

Line length for Base 64 encoded messages

Definition at line 575 of file utils.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Buffer size for Base 64 attachment encoding

Definition at line 576 of file utils.c.

Referenced by ast_base64_encode_file(), and inbuf().

Function Documentation

int ast_base64_encode_file ( FILE *  inputfile,
FILE *  outputfile,
const char *  endl 
)

Performs a base 64 encode algorithm on the contents of a File.

Parameters
inputfileA FILE handle to the input file to be encoded. Must be readable. This handle is not automatically closed.
outputfileA FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename.
endlThe line ending to use (e.g. either "\n" or "\r\n")
Returns
zero on success, -1 on error.

Definition at line 648 of file utils.c.

References BASEMAXINLINE, inchar(), and ochar().

Referenced by ast_base64_encode_file_path().

649 {
650  static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
651  'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
652  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
653  '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
654  int i, hiteof = 0;
655  struct baseio bio;
656 
657  memset(&bio, 0, sizeof(bio));
658  bio.iocp = BASEMAXINLINE;
659 
660  while (!hiteof){
661  unsigned char igroup[3], ogroup[4];
662  int c, n;
663 
664  memset(igroup, 0, sizeof(igroup));
665 
666  for (n = 0; n < 3; n++) {
667  if ((c = inchar(&bio, inputfile)) == EOF) {
668  hiteof = 1;
669  break;
670  }
671 
672  igroup[n] = (unsigned char) c;
673  }
674 
675  if (n > 0) {
676  ogroup[0]= dtable[igroup[0] >> 2];
677  ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
678  ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
679  ogroup[3]= dtable[igroup[2] & 0x3F];
680 
681  if (n < 3) {
682  ogroup[3] = '=';
683 
684  if (n < 2) {
685  ogroup[2] = '=';
686  }
687  }
688 
689  for (i = 0; i < 4; i++) {
690  ochar(&bio, ogroup[i], outputfile, endl);
691  }
692  }
693  }
694 
695  if (fputs(endl, outputfile) == EOF) {
696  return 0;
697  }
698 
699  return 1;
700 }
static int inchar(struct baseio *bio, FILE *fi)
utility used by base_encode()
Definition: utils.c:615
Structure used for base64 encoding.
Definition: utils.c:579
static int ochar(struct baseio *bio, int c, FILE *so, const char *endl)
utility used by base_encode()
Definition: utils.c:629
#define BASEMAXINLINE
Definition: utils.c:576
int ast_base64_encode_file_path ( const char *  filename,
FILE *  outputfile,
const char *  endl 
)

Performs a base 64 encode algorithm on the contents of a File.

Parameters
filenameThe path to the file to be encoded. Must be readable, file is opened in read mode.
outputfileA FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename.
endlThe line ending to use (e.g. either "\n" or "\r\n")
Returns
zero on success, -1 on error.

Definition at line 702 of file utils.c.

References ast_base64_encode_file().

703 {
704  FILE *fi;
705  int res;
706 
707  if (!(fi = fopen(filename, "rb"))) {
708  ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
709  return -1;
710  }
711 
712  res = ast_base64_encode_file(fi, outputfile, endl);
713 
714  fclose(fi);
715 
716  return res;
717 }
int ast_base64_encode_file(FILE *inputfile, FILE *outputfile, const char *endl)
Performs a base 64 encode algorithm on the contents of a File.
Definition: utils.c:648
int ast_base64decode ( unsigned char *  dst,
const char *  src,
int  max 
)

decode BASE64 encoded text

Decode data from base64.

Definition at line 296 of file utils.c.

Referenced by ast_base64decode_string(), ast_check_signature(), and ast_http_get_auth().

297 {
298  int cnt = 0;
299  unsigned int byte = 0;
300  unsigned int bits = 0;
301  int incnt = 0;
302  while(*src && *src != '=' && (cnt < max)) {
303  /* Shift in 6 bits of input */
304  byte <<= 6;
305  byte |= (b2a[(int)(*src)]) & 0x3f;
306  bits += 6;
307  src++;
308  incnt++;
309  /* If we have at least 8 bits left over, take that character
310  off the top */
311  if (bits >= 8) {
312  bits -= 8;
313  *dst = (byte >> bits) & 0xff;
314  dst++;
315  cnt++;
316  }
317  }
318  /* Don't worry about left over bits, they're extra anyway */
319  return cnt;
320 }
char* ast_base64decode_string ( const char *  src)

Decode BASE64 encoded text and return the string.

Same as ast_base64decode, but does the math for you and returns a decoded string.

Definition at line 323 of file utils.c.

References ast_base64decode(), and ast_malloc.

324 {
325  size_t encoded_len;
326  size_t decoded_len;
327  int padding = 0;
328  unsigned char *decoded_string;
329 
330  if (ast_strlen_zero(src)) {
331  return NULL;
332  }
333 
334  encoded_len = strlen(src);
335  if (encoded_len > 2 && src[encoded_len - 1] == '=') {
336  padding++;
337  if (src[encoded_len - 2] == '=') {
338  padding++;
339  }
340  }
341 
342  decoded_len = (encoded_len / 4 * 3) - padding;
343  decoded_string = ast_malloc(decoded_len + 1);
344  if (!decoded_string) {
345  return NULL;
346  }
347 
348  ast_base64decode(decoded_string, src, decoded_len);
349  decoded_string[decoded_len] = '\0';
350 
351  return (char *)decoded_string;
352 }
int ast_base64decode(unsigned char *dst, const char *src, int max)
decode BASE64 encoded text
Definition: utils.c:296
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
int ast_base64encode ( char *  dst,
const unsigned char *  src,
int  srclen,
int  max 
)

Encode data in base64.

Parameters
dstthe destination buffer
srcthe source data to be encoded
srclenthe number of bytes present in the source buffer
maxthe maximum number of bytes to write into the destination buffer, including the terminating NULL character.

Definition at line 406 of file utils.c.

References ast_base64encode_full().

Referenced by ast_base64encode_string(), ast_sign(), and xmpp_client_authenticate_sasl().

407 {
408  return ast_base64encode_full(dst, src, srclen, max, 0);
409 }
int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
encode text to BASE64 coding
Definition: utils.c:355
char* ast_base64encode_string ( const char *  src)

Encode to BASE64 and return encoded string.

Same as ast_base64encode, but does hte math for you and returns an encoded string.

Definition at line 412 of file utils.c.

References ast_base64encode(), and ast_calloc.

413 {
414  size_t encoded_len;
415  char *encoded_string;
416 
417  if (ast_strlen_zero(src)) {
418  return NULL;
419  }
420 
421  encoded_len = ((strlen(src) * 4 / 3 + 3) & ~3) + 1;
422  encoded_string = ast_calloc(1, encoded_len);
423 
424  ast_base64encode(encoded_string, (const unsigned char *)src, strlen(src), encoded_len);
425 
426  return encoded_string;
427 }
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: utils.c:406
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int ast_base64url_decode ( unsigned char *  dst,
const char *  src,
int  max 
)

Decode data from base64 URL.

Parameters
dstThe destination buffer
srcThe source buffer
maxThe maximum number of bytes to write into the destination buffer. Note that this function will not ensure that the destination buffer is NULL terminated. So, in general, this parameter should be sizeof(dst) - 1

Definition at line 429 of file utils.c.

Referenced by ast_base64url_decode_string().

430 {
431  int cnt = 0;
432  unsigned int byte = 0;
433  unsigned int bits = 0;
434 
435  while (*src && (cnt < max)) {
436  byte <<= 6;
437  byte |= (b2a_url[(int)(*src)]) & 0x3f;
438  bits += 6;
439  src++;
440  if (bits >= 8) {
441  bits -= 8;
442  *dst = (byte >> bits) & 0xff;
443  dst++;
444  cnt++;
445  }
446  }
447  return cnt;
448 }
char* ast_base64url_decode_string ( const char *  src)

Decode string from base64 URL.

Note
The returned string will need to be freed later
Parameters
srcThe source buffer
Return values
NULLon failure
Returns
Decoded string on success

Definition at line 450 of file utils.c.

References ast_base64url_decode(), and ast_malloc.

451 {
452  size_t decoded_len;
453  unsigned char *decoded_string;
454 
455  if (ast_strlen_zero(src)) {
456  return NULL;
457  }
458 
459  decoded_len = strlen(src) * 3 / 4;
460  decoded_string = ast_malloc(decoded_len + 1);
461  if (!decoded_string) {
462  return NULL;
463  }
464 
465  ast_base64url_decode(decoded_string, src, decoded_len);
466  decoded_string[decoded_len] = '\0';
467 
468  return (char *)decoded_string;
469 }
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
int ast_base64url_decode(unsigned char *dst, const char *src, int max)
Decode data from base64 URL.
Definition: utils.c:429
int ast_base64url_encode ( char *  dst,
const unsigned char *  src,
int  srclen,
int  max 
)

Encode data in base64 URL.

Parameters
dstThe destination buffer
srcThe source data to be encoded
srclenThe number of bytes present in the source buffer
maxThe maximum number of bytes to write into the destination buffer, including the terminating NULL character

Definition at line 518 of file utils.c.

References ast_base64url_encode_full().

Referenced by ast_base64url_encode_string().

519 {
520  return ast_base64url_encode_full(dst, src, srclen, max, 0);
521 }
int ast_base64url_encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
Same as ast_base64encode_full but for base64 URL.
Definition: utils.c:471
int ast_base64url_encode_full ( char *  dst,
const unsigned char *  src,
int  srclen,
int  max,
int  linebreaks 
)

Same as ast_base64encode_full but for base64 URL.

Parameters
dstThe destination buffer
srcThe source buffer
srclenThe number of bytes present in the source buffer
maxThe maximum number of bytes to write into the destination buffer, including the terminating NULL character.
linebreaksSet to 1 if there should be linebreaks inserted in the result

Definition at line 471 of file utils.c.

Referenced by ast_base64url_encode().

472 {
473  int cnt = 0;
474  int col = 0;
475  unsigned int byte = 0;
476  int bits = 0;
477  int cntin = 0;
478 
479  max--;
480  while ((cntin < srclen) && (cnt < max)) {
481  byte <<= 8;
482  byte |= *(src++);
483  bits += 8;
484  cntin++;
485  if ((bits == 24) && (cnt + 4 <= max)) {
486  *dst++ = base64url[(byte >> 18) & 0x3f];
487  *dst++ = base64url[(byte >> 12) & 0x3f];
488  *dst++ = base64url[(byte >> 6) & 0x3f];
489  *dst++ = base64url[(byte) & 0x3f];
490  cnt += 4;
491  col += 4;
492  bits = 0;
493  byte = 0;
494  }
495  if (linebreaks && (cnt < max) && (col == 64)) {
496  *dst++ = '\n';
497  cnt++;
498  col = 0;
499  }
500  }
501  if (bits && (cnt + 4 <= max)) {
502  byte <<= 24 - bits;
503  *dst++ = base64url[(byte >> 18) & 0x3f];
504  *dst++ = base64url[(byte >> 12) & 0x3f];
505  if (bits == 16) {
506  *dst++ = base64url[(byte >> 6) & 0x3f];
507  }
508  cnt += 4;
509  }
510  if (linebreaks && (cnt < max)) {
511  *dst++ = '\n';
512  cnt++;
513  }
514  *dst = '\0';
515  return cnt;
516 }
char* ast_base64url_encode_string ( const char *  src)

Encode string in base64 URL.

Note
The returned string will need to be freed later
Parameters
srcThe source data to be encoded
Return values
NULLon failure
Returns
Encoded string on success

Definition at line 523 of file utils.c.

References ast_base64url_encode(), and ast_malloc.

524 {
525  size_t encoded_len;
526  char *encoded_string;
527 
528  if (ast_strlen_zero(src)) {
529  return NULL;
530  }
531 
532  encoded_len = ((strlen(src) * 4 / 3 + 3) & ~3) + 1;
533  encoded_string = ast_malloc(encoded_len);
534 
535  ast_base64url_encode(encoded_string, (const unsigned char *)src, strlen(src), encoded_len);
536 
537  return encoded_string;
538 }
int ast_base64url_encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64 URL.
Definition: utils.c:518
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
int ast_build_string ( char **  buffer,
size_t *  space,
const char *  fmt,
  ... 
)

Build a string in a buffer, designed to be called repeatedly.

Note
This method is not recommended. New code should use ast_str_*() instead.

This is a wrapper for snprintf, that properly handles the buffer pointer and buffer space available.

Parameters
buffercurrent position in buffer to place string into (will be updated on return)
spaceremaining space in buffer (will be updated on return)
fmtprintf-style format string
Return values
0on success
non-zeroon failure.

Definition at line 2167 of file utils.c.

References ast_build_string_va().

Referenced by generate_filenames_string().

2168 {
2169  va_list ap;
2170  int result;
2171 
2172  va_start(ap, fmt);
2173  result = ast_build_string_va(buffer, space, fmt, ap);
2174  va_end(ap);
2175 
2176  return result;
2177 }
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: utils.c:2148
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.

This is a wrapper for snprintf, that properly handles the buffer pointer and buffer space available.

Return values
zeroon success.
non-zeroon failure.
Parameters
buffercurrent position in buffer to place string into (will be updated on return)
spaceremaining space in buffer (will be updated on return)
fmtprintf-style format string
apvarargs list of arguments for format

Definition at line 2148 of file utils.c.

Referenced by ast_build_string().

2149 {
2150  int result;
2151 
2152  if (!buffer || !*buffer || !space || !*space)
2153  return -1;
2154 
2155  result = vsnprintf(*buffer, *space, fmt, ap);
2156 
2157  if (result < 0)
2158  return -1;
2159  else if (result > *space)
2160  result = *space;
2161 
2162  *buffer += result;
2163  *space -= result;
2164  return 0;
2165 }
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.

Try to write string, but wait no more than ms milliseconds before timing out.

Note
The code assumes that the file descriptor has NONBLOCK set, so there is only one system call made to do a write, unless we actually have a need to wait. This way, we get better performance. If the descriptor is blocking, all assumptions on the guaranteed detail do not apply anymore.

Definition at line 1771 of file utils.c.

References ast_debug, ast_tvdiff_ms(), and ast_tvnow().

1772 {
1773  struct timeval start = ast_tvnow();
1774  int res = 0;
1775  int elapsed = 0;
1776 
1777  while (len) {
1778  if (wait_for_output(fd, timeoutms - elapsed)) {
1779  return -1;
1780  }
1781 
1782  res = write(fd, s, len);
1783 
1784  if (res < 0 && errno != EAGAIN && errno != EINTR) {
1785  /* fatal error from write() */
1786  if (errno == EPIPE) {
1787 #ifndef STANDALONE
1788  ast_debug(1, "write() failed due to reading end being closed: %s\n", strerror(errno));
1789 #endif
1790  } else {
1791  ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
1792  }
1793  return -1;
1794  }
1795 
1796  if (res < 0) {
1797  /* It was an acceptable error */
1798  res = 0;
1799  }
1800 
1801  /* Update how much data we have left to write */
1802  len -= res;
1803  s += res;
1804  res = 0;
1805 
1806  elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1807  if (elapsed >= timeoutms) {
1808  /* We've taken too long to write
1809  * This is only an error condition if we haven't finished writing. */
1810  res = len ? -1 : 0;
1811  break;
1812  }
1813  }
1814 
1815  return res;
1816 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
#define ast_debug(level,...)
Log a DEBUG message.
int ast_check_command_in_path ( const char *  cmd)

Test for the presence of an executable command in $PATH.

Parameters
cmdName of command to locate.
Return values
True(non-zero) if command is in $PATH.
False(zero) command not found.

Definition at line 3263 of file utils.c.

References ast_strdup.

3264 {
3265  char *token, *saveptr, *path = getenv("PATH");
3266  char filename[PATH_MAX];
3267  int len;
3268 
3269  if (path == NULL) {
3270  return 0;
3271  }
3272 
3273  path = ast_strdup(path);
3274  if (path == NULL) {
3275  return 0;
3276  }
3277 
3278  token = strtok_r(path, ":", &saveptr);
3279  while (token != NULL) {
3280  len = snprintf(filename, sizeof(filename), "%s/%s", token, cmd);
3281  if (len < 0 || len >= sizeof(filename)) {
3282  ast_log(LOG_WARNING, "Path constructed with '%s' too long; skipping\n", token);
3283  continue;
3284  }
3285 
3286  if (access(filename, X_OK) == 0) {
3287  ast_free(path);
3288  return 1;
3289  }
3290 
3291  token = strtok_r(NULL, ":", &saveptr);
3292  }
3293  ast_free(path);
3294  return 0;
3295 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
int ast_check_ipv6 ( void  )

Test that an OS supports IPv6 Networking.

Since
13.14.0
Return values
True(non-zero) if the IPv6 supported.
False(zero) if the OS doesn't support IPv6.

Definition at line 2792 of file utils.c.

Referenced by load_module().

2793 {
2794  int udp6_socket = socket(AF_INET6, SOCK_DGRAM, 0);
2795 
2796  if (udp6_socket < 0) {
2797  return 0;
2798  }
2799 
2800  close(udp6_socket);
2801  return 1;
2802 }
int ast_compare_versions ( const char *  version1,
const char *  version2 
)

Compare 2 major.minor.patch.extra version strings.

Since
13.7.0
Parameters
version1
version2
Return values
negativeif version 1 < version 2.
0if version 1 = version 2.
positiveif version 1 > version 2.

Definition at line 3124 of file utils.c.

3125 {
3126  unsigned int major[2] = { 0 };
3127  unsigned int minor[2] = { 0 };
3128  unsigned int patch[2] = { 0 };
3129  unsigned int extra[2] = { 0 };
3130  int res;
3131 
3132  sscanf(version1, "%u.%u.%u.%u", &major[0], &minor[0], &patch[0], &extra[0]);
3133  sscanf(version2, "%u.%u.%u.%u", &major[1], &minor[1], &patch[1], &extra[1]);
3134 
3135  res = major[0] - major[1];
3136  if (res) {
3137  return res;
3138  }
3139  res = minor[0] - minor[1];
3140  if (res) {
3141  return res;
3142  }
3143  res = patch[0] - patch[1];
3144  if (res) {
3145  return res;
3146  }
3147  return extra[0] - extra[1];
3148 }
void DO_CRASH_NORETURN ast_do_crash ( void  )

Force a crash if DO_CRASH is defined.

Note
If DO_CRASH is not defined then the function returns.

Definition at line 2804 of file utils.c.

Referenced by optional_api_create(), and optional_api_user_create().

2805 {
2806 #if defined(DO_CRASH)
2807  abort();
2808  /*
2809  * Just in case abort() doesn't work or something else super
2810  * silly, and for Qwell's amusement.
2811  */
2812  *((int *) 0) = 0;
2813 #endif /* defined(DO_CRASH) */
2814 }
int ast_eid_cmp ( const struct ast_eid eid1,
const struct ast_eid eid2 
)

Compare two EIDs.

Return values
0if the two are the same
non-zerootherwise
Since
1.6.1

Definition at line 3094 of file utils.c.

Referenced by publish_cluster_discovery_to_stasis(), xmpp_pubsub_devstate_cb(), xmpp_pubsub_handle_event(), and xmpp_pubsub_mwi_cb().

3095 {
3096  return memcmp(eid1, eid2, sizeof(*eid1));
3097 }
int ast_eid_is_empty ( const struct ast_eid eid)

Check if EID is empty.

Return values
1if the EID is empty
0otherwise
Since
13.12.0

Definition at line 3099 of file utils.c.

Referenced by load_module().

3100 {
3101  struct ast_eid empty_eid;
3102 
3103  memset(&empty_eid, 0, sizeof(empty_eid));
3104  return memcmp(eid, &empty_eid, sizeof(empty_eid)) ? 0 : 1;
3105 }
An Entity ID is essentially a MAC address, brief and unique.
Definition: utils.h:813
char* ast_eid_to_str ( char *  s,
int  maxlen,
struct ast_eid eid 
)

Convert an EID to a string.

Since
1.6.1

Definition at line 2839 of file utils.c.

Referenced by app_send(), ast_ari_asterisk_get_info(), ast_ari_asterisk_ping(), ast_set_default_eid(), ast_str_retrieve_variable(), do_register(), do_register_expire(), handle_show_settings(), prometheus_config_post_apply(), publish_cluster_discovery_to_stasis_full(), publish_device_state_to_stasis(), publish_mwi_to_stasis(), xmpp_pubsub_publish_device_state(), and xmpp_pubsub_publish_mwi().

2840 {
2841  int x;
2842  char *os = s;
2843  if (maxlen < 18) {
2844  if (s && (maxlen > 0)) {
2845  *s = '\0';
2846  }
2847  } else {
2848  for (x = 0; x < 5; x++) {
2849  sprintf(s, "%02hhx:", eid->eid[x]);
2850  s += 3;
2851  }
2852  sprintf(s, "%02hhx", eid->eid[5]);
2853  }
2854  return os;
2855 }
void ast_enable_packet_fragmentation ( int  sock)

Disable PMTU discovery on a socket.

Parameters
sockThe socket to manipulate

On Linux, UDP sockets default to sending packets with the Dont Fragment (DF) bit set. This is supposedly done to allow the application to do PMTU discovery, but Asterisk does not do this.

Because of this, UDP packets sent by Asterisk that are larger than the MTU of any hop in the path will be lost. This function can be called on a socket to ensure that the DF bit will not be set.

Definition at line 2469 of file utils.c.

2470 {
2471 #if defined(HAVE_IP_MTU_DISCOVER)
2472  int val = IP_PMTUDISC_DONT;
2473 
2474  if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
2475  ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
2476 #endif /* HAVE_IP_MTU_DISCOVER */
2477 }
char* ast_escape ( char *  dest,
const char *  s,
size_t  size,
const char *  to_escape 
)

Escape the 'to_escape' characters in the given string.

Note
The given output buffer will contain a truncated escaped version of the source string if the given buffer is not large enough.
Parameters
destthe escaped string
sthe source string to escape
sizeThe size of the destination buffer
to_escapean array of characters to escape
Returns
Pointer to the destination.

Definition at line 2034 of file utils.c.

References ast_copy_string().

Referenced by ast_escape_alloc().

2035 {
2036  char *p;
2037  char *c;
2038 
2039  if (!dest || !size) {
2040  return dest;
2041  }
2042  if (ast_strlen_zero(s)) {
2043  *dest = '\0';
2044  return dest;
2045  }
2046 
2047  if (ast_strlen_zero(to_escape)) {
2048  ast_copy_string(dest, s, size);
2049  return dest;
2050  }
2051 
2052  for (p = dest; *s && --size; ++s, ++p) {
2053  /* If in the list of characters to escape then escape it */
2054  if (strchr(to_escape, *s)) {
2055  if (!--size) {
2056  /* Not enough room left for the escape sequence. */
2057  break;
2058  }
2059 
2060  /*
2061  * See if the character to escape is part of the standard escape
2062  * sequences. If so we'll have to use its mapped counterpart
2063  * otherwise just use the current character.
2064  */
2065  c = strchr(escape_sequences, *s);
2066  *p++ = '\\';
2067  *p = c ? escape_sequences_map[c - escape_sequences] : *s;
2068  } else {
2069  *p = *s;
2070  }
2071  }
2072  *p = '\0';
2073 
2074  return dest;
2075 }
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
char* ast_escape_alloc ( const char *  s,
const char *  to_escape 
)

Escape the 'to_escape' characters in the given string.

Note
Caller is responsible for freeing the returned string
Parameters
sthe source string to escape
to_escapean array of characters to escape
Returns
Pointer to the escaped string or NULL.

Definition at line 2132 of file utils.c.

References ast_escape().

2133 {
2134  size_t size = 0;
2135  char *dest = escape_alloc(s, &size);
2136 
2137  return ast_escape(dest, s, size, to_escape);
2138 }
char * ast_escape(char *dest, const char *s, size_t size, const char *to_escape)
Escape the 'to_escape' characters in the given string.
Definition: utils.c:2034
char* ast_escape_c ( char *  dest,
const char *  s,
size_t  size 
)

Escape standard 'C' sequences in the given string.

Note
The given output buffer will contain a truncated escaped version of the source string if the given buffer is not large enough.
Parameters
destthe escaped string
sthe source string to escape
sizeThe size of the destination buffer
Returns
Pointer to the escaped string.

Definition at line 2077 of file utils.c.

Referenced by ast_escape_c_alloc().

2078 {
2079  /*
2080  * Note - This is an optimized version of ast_escape. When looking only
2081  * for escape_sequences a couple of checks used in the generic case can
2082  * be left out thus making it slightly more efficient.
2083  */
2084  char *p;
2085  char *c;
2086 
2087  if (!dest || !size) {
2088  return dest;
2089  }
2090  if (ast_strlen_zero(s)) {
2091  *dest = '\0';
2092  return dest;
2093  }
2094 
2095  for (p = dest; *s && --size; ++s, ++p) {
2096  /*
2097  * See if the character to escape is part of the standard escape
2098  * sequences. If so use its mapped counterpart.
2099  */
2100  c = strchr(escape_sequences, *s);
2101  if (c) {
2102  if (!--size) {
2103  /* Not enough room left for the escape sequence. */
2104  break;
2105  }
2106 
2107  *p++ = '\\';
2108  *p = escape_sequences_map[c - escape_sequences];
2109  } else {
2110  *p = *s;
2111  }
2112  }
2113  *p = '\0';
2114 
2115  return dest;
2116 }
char* ast_escape_c_alloc ( const char *  s)

Escape standard 'C' sequences in the given string.

Note
Caller is responsible for freeing the returned string
Parameters
sthe source string to escape
Returns
Pointer to the escaped string or NULL.

Definition at line 2140 of file utils.c.

References ast_escape_c().

Referenced by ast_manager_build_channel_state_string_prefix().

2141 {
2142  size_t size = 0;
2143  char *dest = escape_alloc(s, &size);
2144 
2145  return ast_escape_c(dest, s, size);
2146 }
char * ast_escape_c(char *dest, const char *s, size_t size)
Escape standard 'C' sequences in the given string.
Definition: utils.c:2077
char* ast_escape_quoted ( const char *  string,
char *  outbuf,
int  buflen 
)

Escape characters found in a quoted string.

Note
This function escapes quoted characters based on the 'qdtext' set of allowed characters from RFC 3261 section 25.1.
Parameters
stringstring to be escaped
outbufresulting escaped string
buflensize of output buffer
Returns
a pointer to the escaped string

Definition at line 781 of file utils.c.

782 {
783  const char *ptr = string;
784  char *out = outbuf;
785  char *allow = "\t\v !"; /* allow LWS (minus \r and \n) and "!" */
786 
787  while (*ptr && out - outbuf < buflen - 1) {
788  if (!(strchr(allow, *ptr))
789  && !(*ptr >= '#' && *ptr <= '[') /* %x23 - %x5b */
790  && !(*ptr >= ']' && *ptr <= '~') /* %x5d - %x7e */
791  && !((unsigned char) *ptr > 0x7f)) { /* UTF8-nonascii */
792 
793  if (out - outbuf >= buflen - 2) {
794  break;
795  }
796  out += sprintf(out, "\\%c", (unsigned char) *ptr);
797  } else {
798  *out = *ptr;
799  out++;
800  }
801  ptr++;
802  }
803 
804  if (buflen) {
805  *out = '\0';
806  }
807 
808  return outbuf;
809 }
char* ast_escape_semicolons ( const char *  string,
char *  outbuf,
int  buflen 
)

Escape semicolons found in a string.

Parameters
stringstring to be escaped
outbufresulting escaped string
buflensize of output buffer
Returns
a pointer to the escaped string

Definition at line 811 of file utils.c.

Referenced by ast_config_text_file_save2(), and handle_cli_dialplan_save().

812 {
813  const char *ptr = string;
814  char *out = outbuf;
815 
816  if (string == NULL || outbuf == NULL) {
817  ast_assert(string != NULL && outbuf != NULL);
818  return NULL;
819  }
820 
821  while (*ptr && out - outbuf < buflen - 1) {
822  if (*ptr == ';') {
823  if (out - outbuf >= buflen - 2) {
824  break;
825  }
826  strcpy(out, "\\;");
827  out += 2;
828  } else {
829  *out = *ptr;
830  out++;
831  }
832  ptr++;
833  }
834 
835  if (buflen) {
836  *out = '\0';
837  }
838 
839  return outbuf;
840 }
int ast_false ( const char *  val)

Make sure something is false. Determine if a string containing a boolean value is "false". This function checks to see whether a string passed to it is an indication of an "false" value. It checks to see if the string is "no", "false", "n", "f", "off" or "0".

Return values
-1if "true".
0otherwise, like NUL pointer.

Definition at line 2216 of file utils.c.

Referenced by acf_faxopt_write(), bool_handler_fn(), boolflag_handler_fn(), build_peer(), build_user(), load_config(), manager_mute_mixmonitor(), parking_feature_flag_cfg(), reload_single_member(), rt_handle_member_record(), rtp_reload(), run_agi(), set_config(), and strings_to_mask().

2217 {
2218  if (ast_strlen_zero(s))
2219  return 0;
2220 
2221  /* Determine if this is a false value */
2222  if (!strcasecmp(s, "no") ||
2223  !strcasecmp(s, "false") ||
2224  !strcasecmp(s, "n") ||
2225  !strcasecmp(s, "f") ||
2226  !strcasecmp(s, "0") ||
2227  !strcasecmp(s, "off"))
2228  return -1;
2229 
2230  return 0;
2231 }
int ast_file_is_readable ( const char *  filename)

Test that a file exists and is readable by the effective user.

Since
13.7.0
Parameters
filenameFile to test.
Return values
True(non-zero) if the file exists and is readable.
False(zero) if the file either doesn't exists or is not readable.

Definition at line 3107 of file utils.c.

Referenced by ast_media_cache_retrieve(), and ast_rtp_dtls_cfg_parse().

3108 {
3109 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
3110 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
3111 #define eaccess euidaccess
3112 #endif
3113  return eaccess(filename, R_OK) == 0;
3114 #else
3115  int fd = open(filename, O_RDONLY | O_NONBLOCK);
3116  if (fd < 0) {
3117  return 0;
3118  }
3119  close(fd);
3120  return 1;
3121 #endif
3122 }
void ast_format_duration_hh_mm_ss ( int  duration,
char *  buf,
size_t  length 
)

Formats a duration into HH:MM:SS.

Since
12
Parameters
durationThe time (in seconds) to format
bufA buffer to hold the formatted string'
lengthThe size of the buffer

Definition at line 2297 of file utils.c.

2298 {
2299  int durh, durm, durs;
2300  durh = duration / 3600;
2301  durm = (duration % 3600) / 60;
2302  durs = duration % 60;
2303  snprintf(buf, length, "%02d:%02d:%02d", durh, durm, durs);
2304 }
int ast_get_tid ( void  )

Get current thread ID.

Returns
the ID if platform is supported, else -1

Definition at line 2752 of file utils.c.

Referenced by ast_hangup().

2753 {
2754  int ret = -1;
2755 #if defined (__linux) && defined(SYS_gettid)
2756  ret = syscall(SYS_gettid); /* available since Linux 1.4.11 */
2757 #elif defined(__sun)
2758  ret = pthread_self();
2759 #elif defined(__APPLE__)
2760  ret = mach_thread_self();
2761  mach_port_deallocate(mach_task_self(), ret);
2762 #elif defined(__FreeBSD__)
2763  long lwpid;
2764  thr_self(&lwpid);
2765  ret = lwpid;
2766 #elif defined(__NetBSD__)
2767  ret = _lwp_self();
2768 #elif defined(__OpenBSD__)
2769  ret = getthrid();
2770 #endif
2771  return ret;
2772 }
int ast_get_time_t ( const char *  src,
time_t *  dst,
time_t  _default,
int *  consumed 
)

get values from config variables.

Parse a time (integer) string.

Definition at line 2446 of file utils.c.

Referenced by realtime_peer().

2447 {
2448  long t;
2449  int scanned;
2450 
2451  if (dst == NULL)
2452  return -1;
2453 
2454  *dst = _default;
2455 
2456  if (ast_strlen_zero(src))
2457  return -1;
2458 
2459  /* only integer at the moment, but one day we could accept more formats */
2460  if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
2461  *dst = t;
2462  if (consumed)
2463  *consumed = scanned;
2464  return 0;
2465  } else
2466  return -1;
2467 }
int ast_get_timeval ( const char *  src,
struct timeval *  dst,
struct timeval  _default,
int *  consumed 
)

get values from config variables.

Parse a time (float) string.

Definition at line 2419 of file utils.c.

Referenced by timeval_str2struct().

2420 {
2421  long double dtv = 0.0;
2422  int scanned;
2423 
2424  if (dst == NULL)
2425  return -1;
2426 
2427  *dst = _default;
2428 
2429  if (ast_strlen_zero(src))
2430  return -1;
2431 
2432  /* only integer at the moment, but one day we could accept more formats */
2433  if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
2434  dst->tv_sec = dtv;
2435  dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
2436  if (consumed)
2437  *consumed = scanned;
2438  return 0;
2439  } else
2440  return -1;
2441 }
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 not thread safe)

Thread-safe gethostbyname function to use in Asterisk.

Definition at line 199 of file utils.c.

200 {
201 #ifndef HAVE_GETHOSTBYNAME_R_5
202  int res;
203 #endif
204  int herrno;
205  int dots = 0;
206  const char *s;
207  struct hostent *result = NULL;
208  /* Although it is perfectly legitimate to lookup a pure integer, for
209  the sake of the sanity of people who like to name their peers as
210  integers, we break with tradition and refuse to look up a
211  pure integer */
212  s = host;
213  while (s && *s) {
214  if (*s == '.')
215  dots++;
216  else if (!isdigit(*s))
217  break;
218  s++;
219  }
220  if (!s || !*s) {
221  /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
222  if (dots != 3)
223  return NULL;
224  memset(hp, 0, sizeof(struct ast_hostent));
225  hp->hp.h_addrtype = AF_INET;
226  hp->hp.h_addr_list = (void *) hp->buf;
227  hp->hp.h_addr = hp->buf + sizeof(void *);
228  /* For AF_INET, this will always be 4 */
229  hp->hp.h_length = 4;
230  if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
231  return &hp->hp;
232  return NULL;
233 
234  }
235 #ifdef HAVE_GETHOSTBYNAME_R_5
236  result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
237 
238  if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
239  return NULL;
240 #else
241  res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
242 
243  if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
244  return NULL;
245 #endif
246  return &hp->hp;
247 }
const char* ast_inet_ntoa ( struct in_addr  ia)

ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa

thread-safe replacement for inet_ntoa().

Definition at line 928 of file utils.c.

References ast_threadstorage_get().

Referenced by _stun_show_status(), ast_parse_arg(), rtp_add_candidates_to_ice(), rtp_reload(), score_address(), and stun_monitor_request().

929 {
930  char *buf;
931 
932  if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
933  return "";
934 
935  return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
936 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
void ast_join_delim ( char *  s,
size_t  len,
const char *const  w[],
unsigned int  size,
char  delim 
)

Join an array of strings into a single string.

Parameters
sthe resulting string buffer
lenthe length of the result buffer, s
wan array of strings to join.
sizethe number of elements to join
delimdelimiter between elements

This function will join all of the strings in the array 'w' into a single string. It will also place 'delim' in the result buffer in between each string from 'w'.

Since
12

Definition at line 2378 of file utils.c.

2379 {
2380  int x, ofs = 0;
2381  const char *src;
2382 
2383  /* Join words into a string */
2384  if (!s)
2385  return;
2386  for (x = 0; ofs < len && x < size && w[x] ; x++) {
2387  if (x > 0)
2388  s[ofs++] = delim;
2389  for (src = w[x]; *src && ofs < len; src++)
2390  s[ofs++] = *src;
2391  }
2392  if (ofs == len)
2393  ofs--;
2394  s[ofs] = '\0';
2395 }
void ast_md5_hash ( char *  output,
const char *  input 
)

Produce 32 char MD5 hash of value.

Produces MD5 hash based on input string.

Definition at line 250 of file utils.c.

251 {
252  struct MD5Context md5;
253  unsigned char digest[16];
254  char *ptr;
255  int x;
256 
257  MD5Init(&md5);
258  MD5Update(&md5, (const unsigned char *) input, strlen(input));
259  MD5Final(digest, &md5);
260  ptr = output;
261  for (x = 0; x < 16; x++)
262  ptr += sprintf(ptr, "%02hhx", digest[x]);
263 }
Definition: md5.h:26
int ast_mkdir ( const char *  path,
int  mode 
)

Recursively create directory path.

Parameters
pathThe directory path to create
modeThe permissions with which to try to create the directory
Return values
0on success
Returns
error code otherwise

Creates a directory path, creating parent directories as needed.

Definition at line 2479 of file utils.c.

References ast_alloca, and ast_strdupa.

Referenced by ast_file_fdtemp(), ast_logger_rotate_channel(), create_dirpath(), init_logger(), remove_from_queue(), setup_privacy_args(), sms_nextoutgoing(), and sms_writefile().

2480 {
2481  char *ptr;
2482  int len = strlen(path), count = 0, x, piececount = 0;
2483  char *tmp = ast_strdupa(path);
2484  char **pieces;
2485  char *fullpath = ast_alloca(len + 1);
2486  int res = 0;
2487 
2488  for (ptr = tmp; *ptr; ptr++) {
2489  if (*ptr == '/')
2490  count++;
2491  }
2492 
2493  /* Count the components to the directory path */
2494  pieces = ast_alloca(count * sizeof(*pieces));
2495  for (ptr = tmp; *ptr; ptr++) {
2496  if (*ptr == '/') {
2497  *ptr = '\0';
2498  pieces[piececount++] = ptr + 1;
2499  }
2500  }
2501 
2502  *fullpath = '\0';
2503  for (x = 0; x < piececount; x++) {
2504  /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
2505  strcat(fullpath, "/");
2506  strcat(fullpath, pieces[x]);
2507  res = mkdir(fullpath, mode);
2508  if (res && errno != EEXIST)
2509  return errno;
2510  }
2511  return 0;
2512 }
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
int ast_parse_digest ( const char *  digest,
struct ast_http_digest d,
int  request,
int  pedantic 
)

Parse digest authorization header.

Returns
Returns -1 if we have no auth or something wrong with digest.
Note
This function may be used for Digest request and responce header. request arg is set to nonzero, if we parse Digest Request. pedantic arg can be set to nonzero if we need to do addition Digest check.

Definition at line 2638 of file utils.c.

References ast_skip_blanks(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_string_field_ptr_set, ast_string_field_set, and ast_unescape_c().

2638  {
2639  char *c;
2640  struct ast_str *str = ast_str_create(16);
2641 
2642  /* table of recognised keywords, and places where they should be copied */
2643  const struct x {
2644  const char *key;
2645  const ast_string_field *field;
2646  } *i, keys[] = {
2647  { "username=", &d->username },
2648  { "realm=", &d->realm },
2649  { "nonce=", &d->nonce },
2650  { "uri=", &d->uri },
2651  { "domain=", &d->domain },
2652  { "response=", &d->response },
2653  { "cnonce=", &d->cnonce },
2654  { "opaque=", &d->opaque },
2655  /* Special cases that cannot be directly copied */
2656  { "algorithm=", NULL },
2657  { "qop=", NULL },
2658  { "nc=", NULL },
2659  { NULL, 0 },
2660  };
2661 
2662  if (ast_strlen_zero(digest) || !d || !str) {
2663  ast_free(str);
2664  return -1;
2665  }
2666 
2667  ast_str_set(&str, 0, "%s", digest);
2668 
2669  c = ast_skip_blanks(ast_str_buffer(str));
2670 
2671  if (strncasecmp(c, "Digest ", strlen("Digest "))) {
2672  ast_log(LOG_WARNING, "Missing Digest.\n");
2673  ast_free(str);
2674  return -1;
2675  }
2676  c += strlen("Digest ");
2677 
2678  /* lookup for keys/value pair */
2679  while (c && *c && *(c = ast_skip_blanks(c))) {
2680  /* find key */
2681  for (i = keys; i->key != NULL; i++) {
2682  char *src, *separator;
2683  int unescape = 0;
2684  if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
2685  continue;
2686  }
2687 
2688  /* Found. Skip keyword, take text in quotes or up to the separator. */
2689  c += strlen(i->key);
2690  if (*c == '"') {
2691  src = ++c;
2692  separator = "\"";
2693  unescape = 1;
2694  } else {
2695  src = c;
2696  separator = ",";
2697  }
2698  strsep(&c, separator); /* clear separator and move ptr */
2699  if (unescape) {
2700  ast_unescape_c(src);
2701  }
2702  if (i->field) {
2703  ast_string_field_ptr_set(d, i->field, src);
2704  } else {
2705  /* Special cases that require additional processing */
2706  if (!strcasecmp(i->key, "algorithm=")) {
2707  if (strcasecmp(src, "MD5")) {
2708  ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src);
2709  ast_free(str);
2710  return -1;
2711  }
2712  } else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) {
2713  d->qop = 1;
2714  } else if (!strcasecmp(i->key, "nc=")) {
2715  unsigned long u;
2716  if (sscanf(src, "%30lx", &u) != 1) {
2717  ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src);
2718  ast_free(str);
2719  return -1;
2720  }
2721  ast_string_field_set(d, nc, src);
2722  }
2723  }
2724  break;
2725  }
2726  if (i->key == NULL) { /* not found, try ',' */
2727  strsep(&c, ",");
2728  }
2729  }
2730  ast_free(str);
2731 
2732  /* Digest checkout */
2733  if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
2734  /* "realm" and "nonce" MUST be always exist */
2735  return -1;
2736  }
2737 
2738  if (!request) {
2739  /* Additional check for Digest response */
2740  if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) {
2741  return -1;
2742  }
2743 
2744  if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
2745  return -1;
2746  }
2747  }
2748 
2749  return 0;
2750 }
#define ast_string_field_ptr_set(x, ptr, data)
Set a field to a simple string value.
Definition: stringfields.h:475
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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:1113
Support for dynamic strings.
Definition: strings.h:623
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
char * ast_unescape_c(char *src)
Convert some C escape sequences.
Definition: utils.c:1983
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
char* ast_process_quotes_and_slashes ( char *  start,
char  find,
char  replace_with 
)

Process a string to find and replace characters.

Parameters
startThe string to analyze
findThe character to find
replace_withThe character that will replace the one we are looking for

Definition at line 2352 of file utils.c.

2353 {
2354  char *dataPut = start;
2355  int inEscape = 0;
2356  int inQuotes = 0;
2357 
2358  for (; *start; start++) {
2359  if (inEscape) {
2360  *dataPut++ = *start; /* Always goes verbatim */
2361  inEscape = 0;
2362  } else {
2363  if (*start == '\\') {
2364  inEscape = 1; /* Do not copy \ into the data */
2365  } else if (*start == '\'') {
2366  inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
2367  } else {
2368  /* Replace , with |, unless in quotes */
2369  *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2370  }
2371  }
2372  }
2373  if (start != dataPut)
2374  *dataPut = 0;
2375  return dataPut;
2376 }
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".

This function will trim one leading / and one trailing / from a given input string ast_str regex_pattern must be preallocated before calling this function

Return values
0on success, non-zero on failure.
1if we only stripped a leading /
2if we only stripped a trailing /
3if we did not strip any / characters
Parameters
regex_stringthe string containing /regex/
regex_patternthe destination ast_str which will contain "regex" after execution

Definition at line 2179 of file utils.c.

References ast_str_set(), and ast_str_truncate().

Referenced by ast_manager_hangup_helper().

2180 {
2181  int regex_len = strlen(regex_string);
2182  int ret = 3;
2183 
2184  /* Chop off the leading / if there is one */
2185  if ((regex_len >= 1) && (regex_string[0] == '/')) {
2186  ast_str_set(regex_pattern, 0, "%s", regex_string + 1);
2187  ret -= 2;
2188  }
2189 
2190  /* Chop off the ending / if there is one */
2191  if ((regex_len > 1) && (regex_string[regex_len - 1] == '/')) {
2192  ast_str_truncate(*regex_pattern, -1);
2193  ret -= 1;
2194  }
2195 
2196  return ret;
2197 }
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:786
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:1113
int ast_remaining_ms ( struct timeval  start,
int  max_ms 
)

Calculate remaining milliseconds given a starting timestamp and upper bound.

If the upper bound is negative then this indicates that there is no upper bound on the amount of time to wait. This will result in a negative return.

Parameters
startWhen timing started being calculated
max_msThe maximum number of milliseconds to wait from start. May be negative.
Returns
The number of milliseconds left to wait for. May be negative.

Definition at line 2281 of file utils.c.

References ast_tvdiff_ms(), and ast_tvnow().

Referenced by __ast_answer(), __ast_request_and_dial(), ast_iostream_write(), ast_recvtext(), ast_stun_request(), ast_waitfordigit_full(), generic_fax_exec(), parking_set_duration(), read_mf_digits(), read_sf_digits(), safe_sleep_conditional(), and wait_for_answer().

2282 {
2283  int ms;
2284 
2285  if (max_ms < 0) {
2286  ms = max_ms;
2287  } else {
2288  ms = max_ms - ast_tvdiff_ms(ast_tvnow(), start);
2289  if (ms < 0) {
2290  ms = 0;
2291  }
2292  }
2293 
2294  return ms;
2295 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
void ast_replace_subargument_delimiter ( char *  s)

Replace '^' in a string with ','.

Parameters
sString within which to replace characters

Definition at line 2343 of file utils.c.

Referenced by ast_bridge_set_after_go_on(), dial_exec_full(), and queue_exec().

2344 {
2345  for (; *s; s++) {
2346  if (*s == '^') {
2347  *s = ',';
2348  }
2349  }
2350 }
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.

If base_path does not exist, it will not be created and this function returns EPERM.

Parameters
base_path
pathThe directory path to create
modeThe permissions with which to try to create the directory
Return values
0on success
Returns
an error code otherwise

Definition at line 2584 of file utils.c.

References ast_strdup, and RAII_VAR.

Referenced by stasis_app_control_record().

2585 {
2586  RAII_VAR(char *, absolute_base_path, NULL, ast_std_free);
2587  RAII_VAR(char *, p, NULL, ast_free);
2588 
2589  if (base_path == NULL || path == NULL) {
2590  errno = EFAULT;
2591  return errno;
2592  }
2593 
2594  p = ast_strdup(path);
2595  if (p == NULL) {
2596  errno = ENOMEM;
2597  return errno;
2598  }
2599 
2600  absolute_base_path = realpath(base_path, NULL);
2601  if (absolute_base_path == NULL) {
2602  return errno;
2603  }
2604 
2605  return safe_mkdir(absolute_base_path, p, mode);
2606 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#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:941
void ast_set_default_eid ( struct ast_eid eid)

Fill in an ast_eid with the default eid of this machine.

Since
1.6.1

Definition at line 3001 of file utils.c.

References ast_debug, ast_eid_to_str(), and ast_malloc.

3002 {
3003  int s;
3004  int i;
3005  struct ifreq *ifr;
3006  struct ifreq *ifrp;
3007  struct ifconf ifc;
3008  char *buf = NULL;
3009  char eid_str[20];
3010  int bufsz, num_interfaces;
3011  unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
3012  unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
3013 
3014  s = socket(AF_INET, SOCK_STREAM, 0);
3015  if (s < 0) {
3016  ast_log(LOG_WARNING, "Unable to open socket for seeding global EID. "
3017  "You will have to set it manually.\n");
3018  return;
3019  }
3020 
3021  ifc.ifc_len = 0;
3022  ifc.ifc_buf = NULL;
3023  if (ioctl(s, SIOCGIFCONF, &ifc) || ifc.ifc_len <= 0) {
3024  ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
3025  "You will have to set it manually.\n");
3026  close(s);
3027  return;
3028  }
3029  bufsz = ifc.ifc_len;
3030 
3031  if (!(buf = ast_malloc(bufsz))) {
3032  ast_log(LOG_WARNING, "Unable to allocate memory for seeding global EID. "
3033  "You will have to set it manually.\n");
3034  close(s);
3035  return;
3036  }
3037 
3038  ifc.ifc_buf = buf;
3039  if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
3040  ast_log(LOG_WARNING, "Unable to retrieve ethernet interfaces for seeding global EID. "
3041  "You will have to set it manually.\n");
3042  ast_free(buf);
3043  close(s);
3044  return;
3045  }
3046 
3047  ifrp = ifc.ifc_req;
3048  num_interfaces = ifc.ifc_len / sizeof(*ifr);
3049 
3050  for (i = 0; i < num_interfaces; i++) {
3051  ifr = &ifrp[i];
3052  if (!ioctl(s, SIOCGIFHWADDR, ifr)) {
3053  unsigned char *hwaddr = (unsigned char *) ifr->ifr_hwaddr.sa_data;
3054 
3055  if (!(memcmp(hwaddr, &empty_mac, 6) && memcmp(hwaddr, &full_mac, 6))) {
3056  continue;
3057  }
3058 
3059  memcpy(eid, hwaddr, sizeof(*eid));
3060  ast_debug(1, "Seeding global EID '%s' from '%s' using 'siocgifhwaddr'\n",
3061  ast_eid_to_str(eid_str, sizeof(eid_str), eid), ifr->ifr_name);
3062  ast_free(buf);
3063  close(s);
3064  return;
3065  }
3066  }
3067 
3068  ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
3069  "You will have to set it manually.\n");
3070  ast_free(buf);
3071  close(s);
3072 
3073  return;
3074 }
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_debug(level,...)
Log a DEBUG message.
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: utils.c:2839
void ast_sha1_hash ( char *  output,
const char *  input 
)

Produce 40 char SHA1 hash of value.

Produces SHA1 hash based on input string.

Definition at line 266 of file utils.c.

References SHA1Input(), SHA1Reset(), and SHA1Result().

Referenced by ast_tcptls_server_start(), xmpp_client_authenticate_digest(), and xmpp_component_authenticate().

267 {
268  struct SHA1Context sha;
269  char *ptr;
270  int x;
271  uint8_t Message_Digest[20];
272 
273  SHA1Reset(&sha);
274 
275  SHA1Input(&sha, (const unsigned char *) input, strlen(input));
276 
277  SHA1Result(&sha, Message_Digest);
278  ptr = output;
279  for (x = 0; x < 20; x++)
280  ptr += sprintf(ptr, "%02hhx", Message_Digest[x]);
281 }
int SHA1Result(SHA1Context *context, uint8_t Message_Digest[SHA1HashSize])
SHA1Result Returns the resulting 160-bit digest.
Definition: sha1.c:226
int SHA1Reset(SHA1Context *context)
SHA1Reset.
Definition: sha1.c:101
int SHA1Input(SHA1Context *context, const uint8_t *message_array, unsigned length)
SHA1Input.
Definition: sha1.c:133
void ast_sha1_hash_uint ( uint8_t *  digest,
const char *  input 
)

Produce a 20 byte SHA1 hash of value.

Produces SHA1 hash based on input string, stored in uint8_t array.

Definition at line 284 of file utils.c.

References SHA1Input(), SHA1Reset(), and SHA1Result().

285 {
286  struct SHA1Context sha;
287 
288  SHA1Reset(&sha);
289 
290  SHA1Input(&sha, (const unsigned char *) input, strlen(input));
291 
292  SHA1Result(&sha, digest);
293 }
int SHA1Result(SHA1Context *context, uint8_t Message_Digest[SHA1HashSize])
SHA1Result Returns the resulting 160-bit digest.
Definition: sha1.c:226
int SHA1Reset(SHA1Context *context)
SHA1Reset.
Definition: sha1.c:101
int SHA1Input(SHA1Context *context, const uint8_t *message_array, unsigned length)
SHA1Input.
Definition: sha1.c:133
int ast_str_to_eid ( struct ast_eid eid,
const char *  s 
)

Convert a string into an EID.

This function expects an EID in the format: 00:11:22:33:44:55

Return values
0success
non-zerofailure
Since
1.6.1

Definition at line 3077 of file utils.c.

Referenced by xmpp_pubsub_handle_event().

3078 {
3079  unsigned int eid_int[6];
3080  int x;
3081 
3082  if (sscanf(s, "%2x:%2x:%2x:%2x:%2x:%2x", &eid_int[0], &eid_int[1], &eid_int[2],
3083  &eid_int[3], &eid_int[4], &eid_int[5]) != 6) {
3084  return -1;
3085  }
3086 
3087  for (x = 0; x < 6; x++) {
3088  eid->eid[x] = eid_int[x];
3089  }
3090 
3091  return 0;
3092 }
char* ast_strip_quoted ( char *  s,
const char *  beg_quotes,
const char *  end_quotes 
)

Strip leading/trailing whitespace and quotes from a string.

Parameters
sThe string to be stripped (will be modified).
beg_quotesThe list of possible beginning quote characters.
end_quotesThe list of matching ending quote characters.
Returns
The stripped string.

This functions strips all leading and trailing whitespace characters from the input string, and returns a pointer to the resulting string. The string is modified in place.

It can also remove beginning and ending quote (or quote-like) characters, in matching pairs. If the first character of the string matches any character in beg_quotes, and the last character of the string is the matching character in end_quotes, then they are removed from the string.

Examples:

1 ast_strip_quoted(buf, "\"", "\"");
2 ast_strip_quoted(buf, "'", "'");
3 ast_strip_quoted(buf, "[{(", "]})");

Definition at line 1818 of file utils.c.

References ast_strip().

Referenced by ast_callerid_parse(), ast_strsep(), ast_strsep_quoted(), hfp_parse_clip(), and parse_dial_string().

1819 {
1820  char *e;
1821  char *q;
1822 
1823  s = ast_strip(s);
1824  if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
1825  e = s + strlen(s) - 1;
1826  if (*e == *(end_quotes + (q - beg_quotes))) {
1827  s++;
1828  *e = '\0';
1829  }
1830  }
1831 
1832  return s;
1833 }
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
char* ast_strsep ( char **  s,
const char  sep,
uint32_t  flags 
)

Act like strsep but ignore separators inside quotes.

Parameters
sPointer to address of the string to be processed. Will be modified and can't be constant.
sepA single character delimiter.
flagsControls post-processing of the result. AST_STRSEP_TRIM trims all leading and trailing whitespace from the result. If the result containes only whitespace, it'll be passed through unchanged. AST_STRSEP_STRIP does a trim then strips the outermost quotes. You may want to trim again after the strip. Just OR both the TRIM and STRIP flags. AST_STRSEP_UNESCAPE unescapes '\' sequences. AST_STRSEP_ALL does all of the above processing.
Returns
The next token or NULL if done or if there are more than 8 levels of nested quotes. If provided an empty string, will return the empty string.

This function acts like strsep with three exceptions... The separator is a single character instead of a string. Separators inside quotes are treated literally instead of like separators. You can elect to have leading and trailing whitespace and quotes stripped from the result and have '\' sequences unescaped.

Like strsep, ast_strsep maintains no internal state and you can call it recursively using different separators on the same storage.

Also like strsep, for consistent results, consecutive separators are not collapsed so you may get an empty string as a valid result.

Examples:

1 char *mystr = ast_strdupa("abc=def,ghi='zzz=yyy,456',jkl");
2 char *token, *token2, *token3;
3 
4 while((token = ast_strsep(&mystr, ',', AST_STRSEP_STRIP))) {
5  // 1st token will be aaa=def
6  // 2nd token will be ghi='zzz=yyy,456'
7  while((token2 = ast_strsep(&token, '=', AST_STRSEP_STRIP))) {
8  // 1st token2 will be ghi
9  // 2nd token2 will be zzz=yyy,456
10  while((token3 = ast_strsep(&token2, ',', AST_STRSEP_STRIP))) {
11  // 1st token3 will be zzz=yyy
12  // 2nd token3 will be 456
13  // and so on
14  }
15  }
16  // 3rd token will be jkl
17 }

Definition at line 1835 of file utils.c.

References ast_strip(), ast_strip_quoted(), AST_STRSEP_STRIP, AST_STRSEP_TRIM, AST_STRSEP_UNESCAPE, and ast_unescape_quoted().

Referenced by ast_app_getdata_terminator(), ast_sip_header_to_security_mechanism(), ast_sip_security_mechanism_vector_init(), ast_sip_str_to_security_mechanism(), does_category_match(), handle_updates(), and speech_background().

1836 {
1837  char *st = *iss;
1838  char *is;
1839  int inquote = 0;
1840  int found = 0;
1841  char stack[8];
1842 
1843  if (ast_strlen_zero(st)) {
1844  *iss = NULL;
1845  return st;
1846  }
1847 
1848  memset(stack, 0, sizeof(stack));
1849 
1850  for(is = st; *is; is++) {
1851  if (*is == '\\') {
1852  if (*++is != '\0') {
1853  is++;
1854  } else {
1855  break;
1856  }
1857  }
1858 
1859  if (*is == '\'' || *is == '"') {
1860  if (*is == stack[inquote]) {
1861  stack[inquote--] = '\0';
1862  } else {
1863  if (++inquote >= sizeof(stack)) {
1864  return NULL;
1865  }
1866  stack[inquote] = *is;
1867  }
1868  }
1869 
1870  if (*is == sep && !inquote) {
1871  *is = '\0';
1872  found = 1;
1873  *iss = is + 1;
1874  break;
1875  }
1876  }
1877  if (!found) {
1878  *iss = NULL;
1879  }
1880 
1881  if (flags & AST_STRSEP_STRIP) {
1882  st = ast_strip_quoted(st, "'\"", "'\"");
1883  }
1884 
1885  if (flags & AST_STRSEP_TRIM) {
1886  char *trimmed = ast_strip(st);
1887  if (!ast_strlen_zero(trimmed)) {
1888  st = trimmed;
1889  }
1890  }
1891 
1892  if (flags & AST_STRSEP_UNESCAPE) {
1893  ast_unescape_quoted(st);
1894  }
1895 
1896  return st;
1897 }
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: utils.c:1818
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
void ast_unescape_quoted(char *quote_str)
Unescape quotes in a string.
Definition: utils.c:842
char* ast_strsep_quoted ( char **  s,
const char  sep,
const char  quote,
uint32_t  flags 
)

Like ast_strsep() except you can specify a specific quote character.

Parameters
sPointer to address of the string to be processed. Will be modified and can't be constant.
sepA single character delimiter.
quoteThe quote character
flagsControls post-processing of the result. AST_STRSEP_TRIM trims all leading and trailing whitespace from the result. AST_STRSEP_STRIP does a trim then strips the outermost quotes. You may want to trim again after the strip. Just OR both the TRIM and STRIP flags. AST_STRSEP_UNESCAPE unescapes '\' sequences. AST_STRSEP_ALL does all of the above processing.
Returns
The next token or NULL if done or if there are more than 8 levels of nested quotes. If provided an empty string, will return the empty string.

Definition at line 1899 of file utils.c.

References ast_strip(), ast_strip_quoted(), AST_STRSEP_STRIP, AST_STRSEP_TRIM, AST_STRSEP_UNESCAPE, and ast_unescape_quoted().

Referenced by ast_variable_list_from_quoted_string().

1900 {
1901  char *st = *iss;
1902  char *is;
1903  int inquote = 0;
1904  int found = 0;
1905  char stack[8];
1906  const char qstr[] = { quote };
1907 
1908  if (ast_strlen_zero(st)) {
1909  *iss = NULL;
1910  return st;
1911  }
1912 
1913  memset(stack, 0, sizeof(stack));
1914 
1915  for(is = st; *is; is++) {
1916  if (*is == '\\') {
1917  if (*++is != '\0') {
1918  is++;
1919  } else {
1920  break;
1921  }
1922  }
1923 
1924  if (*is == quote) {
1925  if (*is == stack[inquote]) {
1926  stack[inquote--] = '\0';
1927  } else {
1928  if (++inquote >= sizeof(stack)) {
1929  return NULL;
1930  }
1931  stack[inquote] = *is;
1932  }
1933  }
1934 
1935  if (*is == sep && !inquote) {
1936  *is = '\0';
1937  found = 1;
1938  *iss = is + 1;
1939  break;
1940  }
1941  }
1942  if (!found) {
1943  *iss = NULL;
1944  }
1945 
1946  if (flags & AST_STRSEP_STRIP) {
1947  st = ast_strip_quoted(st, qstr, qstr);
1948  }
1949 
1950  if (flags & AST_STRSEP_TRIM) {
1951  char *trimmed = ast_strip(st);
1952  if (!ast_strlen_zero(trimmed)) {
1953  st = trimmed;
1954  }
1955  }
1956 
1957  if (flags & AST_STRSEP_UNESCAPE) {
1958  ast_unescape_quoted(st);
1959  }
1960 
1961  return st;
1962 }
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: utils.c:1818
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
void ast_unescape_quoted(char *quote_str)
Unescape quotes in a string.
Definition: utils.c:842
int ast_thread_is_user_interface ( void  )

Indicates whether the current thread is a user interface.

Return values
True(non-zero) if thread is a user interface.
False(zero) if thread is not a user interface.

Definition at line 3248 of file utils.c.

References ast_threadstorage_get().

Referenced by ast_autoservice_start(), and ast_autoservice_stop().

3249 {
3250  int *thread_user_interface;
3251 
3252  thread_user_interface = ast_threadstorage_get(
3253  &thread_user_interface_tl, sizeof(*thread_user_interface));
3254  if (thread_user_interface == NULL) {
3255  ast_log(LOG_ERROR, "Error checking thread's user interface status\n");
3256  /* On error, assume that we are not a user interface thread */
3257  return 0;
3258  }
3259 
3260  return *thread_user_interface;
3261 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
int ast_thread_user_interface_set ( int  is_user_interface)

Set the current thread's user interface status.

Parameters
is_user_interfaceNon-zero to mark the thread as a user interface.
Return values
True(non-zero) if marking current thread failed.
False(zero) if successfuly marked current thread.

Definition at line 3233 of file utils.c.

References ast_threadstorage_get().

Referenced by handle_tcptls_connection().

3234 {
3235  int *thread_user_interface;
3236 
3237  thread_user_interface = ast_threadstorage_get(
3238  &thread_user_interface_tl, sizeof(*thread_user_interface));
3239  if (thread_user_interface == NULL) {
3240  ast_log(LOG_ERROR, "Error setting user interface status for current thread\n");
3241  return -1;
3242  }
3243 
3244  *thread_user_interface = !!is_user_interface;
3245  return 0;
3246 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
char* ast_to_camel_case_delim ( const char *  s,
const char *  delim 
)

Attempts to convert the given string to camel case using the specified delimiter.

note - returned string needs to be freed

Parameters
sthe string to convert
delimdelimiter to parse out
Returns
The string converted to "CamelCase"
Since
12

Definition at line 2397 of file utils.c.

References ast_copy_string(), and ast_strdup.

2398 {
2399  char *res = ast_strdup(s);
2400  char *front, *back, *buf = res;
2401  int size;
2402 
2403  front = strtok_r(buf, delim, &back);
2404 
2405  while (front) {
2406  size = strlen(front);
2407  *front = toupper(*front);
2408  ast_copy_string(buf, front, size + 1);
2409  buf += size;
2410  front = strtok_r(NULL, delim, &back);
2411  }
2412 
2413  return res;
2414 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_true ( const char *  val)

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".

Return values
-1if "true".
0otherwise, like NULL pointer.

Definition at line 2199 of file utils.c.

Referenced by acf_faxopt_write(), action_status(), apply_general_options(), apply_option(), ast_ari_bridges_add_channel_cb(), ast_ari_bridges_record_cb(), ast_ari_channels_record_cb(), ast_ari_endpoints_refer_cb(), ast_ari_endpoints_refer_to_endpoint_cb(), ast_bridge_timelimit(), ast_jb_read_conf(), ast_rtp_dtls_cfg_parse(), ast_tls_read_conf(), bool_handler_fn(), boolflag_handler_fn(), build_calendar(), build_peer(), build_user(), custom_bitfield_handler(), encoding_format_handler(), func_mute_write(), init_logger_chain(), is_variable_true(), load_config(), manager_mute_mixmonitor(), mbl_load_adapter(), mbl_load_device(), new_realtime_sqlite3_db(), pbx_load_users(), permit_dtmf_interrupt(), pjsip_acf_moh_passthrough_write(), profile_set_param(), queue_rules_set_global_params(), queue_set_global_params(), queue_set_param(), reload_followme(), reload_single_member(), rt_handle_member_record(), rtp_reload(), run_agi(), set_config(), and strings_to_mask().

2200 {
2201  if (ast_strlen_zero(s))
2202  return 0;
2203 
2204  /* Determine if this is a true value */
2205  if (!strcasecmp(s, "yes") ||
2206  !strcasecmp(s, "true") ||
2207  !strcasecmp(s, "y") ||
2208  !strcasecmp(s, "t") ||
2209  !strcasecmp(s, "1") ||
2210  !strcasecmp(s, "on"))
2211  return -1;
2212 
2213  return 0;
2214 }
char* ast_unescape_c ( char *  s)

Convert some C escape sequences.

(\b\f\n\r\t) 

into the equivalent characters. The string to be converted (will be modified).

Returns
The converted string.

Definition at line 1983 of file utils.c.

Referenced by ast_parse_digest().

1984 {
1985  char c, *ret, *dst;
1986 
1987  if (src == NULL)
1988  return NULL;
1989  for (ret = dst = src; (c = *src++); *dst++ = c ) {
1990  if (c != '\\')
1991  continue; /* copy char at the end of the loop */
1992  switch ((c = *src++)) {
1993  case '\0': /* special, trailing '\' */
1994  c = '\\';
1995  break;
1996  case 'b': /* backspace */
1997  c = '\b';
1998  break;
1999  case 'f': /* form feed */
2000  c = '\f';
2001  break;
2002  case 'n':
2003  c = '\n';
2004  break;
2005  case 'r':
2006  c = '\r';
2007  break;
2008  case 't':
2009  c = '\t';
2010  break;
2011  }
2012  /* default, use the char literally */
2013  }
2014  *dst = '\0';
2015  return ret;
2016 }
void ast_unescape_quoted ( char *  quote_str)

Unescape quotes in a string.

Parameters
quote_strThe string with quotes to be unescaped
Note
This function mutates the passed-in string.

Definition at line 842 of file utils.c.

Referenced by ast_callerid_parse(), ast_strsep(), and ast_strsep_quoted().

843 {
844  int esc_pos;
845  int unesc_pos;
846  int quote_str_len = strlen(quote_str);
847 
848  for (esc_pos = 0, unesc_pos = 0;
849  esc_pos < quote_str_len;
850  esc_pos++, unesc_pos++) {
851  if (quote_str[esc_pos] == '\\') {
852  /* at least one more char and current is \\ */
853  esc_pos++;
854  if (esc_pos >= quote_str_len) {
855  break;
856  }
857  }
858 
859  quote_str[unesc_pos] = quote_str[esc_pos];
860  }
861  quote_str[unesc_pos] = '\0';
862 }
char* ast_unescape_semicolon ( char *  s)

Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).

Returns
The stripped string.

Definition at line 1964 of file utils.c.

1965 {
1966  char *e;
1967  char *work = s;
1968 
1969  while ((e = strchr(work, ';'))) {
1970  if ((e > work) && (*(e-1) == '\\')) {
1971  memmove(e - 1, e, strlen(e) + 1);
1972  work = e;
1973  } else {
1974  work = e + 1;
1975  }
1976  }
1977 
1978  return s;
1979 }
void ast_uri_decode ( char *  s,
struct ast_flags  spec 
)

Decode URI, URN, URL (overwrite string)

Note
The ast_uri_http_legacy decode spec flag will cause this function to decode '+' as ' '.
Parameters
sstring to be decoded
specflags describing how the decoding should be performed

Definition at line 762 of file utils.c.

Referenced by ast_http_get_post_vars(), realtime_curl(), realtime_multi_curl(), and uridecode().

763 {
764  char *o;
765  unsigned int tmp;
766 
767  for (o = s; *s; s++, o++) {
768  if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *s == '+') {
769  /* legacy mode, decode '+' as space */
770  *o = ' ';
771  } else if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) {
772  /* have '%', two chars and correct parsing */
773  *o = tmp;
774  s += 2; /* Will be incremented once more when we break out */
775  } else /* all other cases, just copy */
776  *o = *s;
777  }
778  *o = '\0';
779 }
char* ast_uri_encode ( const char *  string,
char *  outbuf,
int  buflen,
struct ast_flags  spec 
)

Turn text string to URI-encoded XX version.

This function encodes characters according to the rules presented in RFC 2396 and/or RFC 3261 section 19.1.2 and section 25.1.

Outbuf needs to have more memory allocated than the instring to have room for the expansion. Every byte that is converted is replaced by three ASCII characters.

Parameters
stringstring to be converted
outbufresulting encoded string
buflensize of output buffer
specflags describing how the encoding should be performed
Returns
a pointer to the uri encoded string

Definition at line 723 of file utils.c.

Referenced by ast_ari_bridges_record(), ast_ari_channels_record(), destroy_curl(), realtime_curl(), realtime_multi_curl(), store_curl(), update_curl(), and uriencode().

724 {
725  const char *ptr = string; /* Start with the string */
726  char *out = outbuf;
727  const char *mark = "-_.!~*'()"; /* no encode set, RFC 2396 section 2.3, RFC 3261 sec 25 */
728  const char *user_unreserved = "&=+$,;?/"; /* user-unreserved set, RFC 3261 sec 25 */
729 
730  while (*ptr && out - outbuf < buflen - 1) {
731  if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *ptr == ' ') {
732  /* for legacy encoding, encode spaces as '+' */
733  *out = '+';
734  out++;
735  } else if (!(ast_test_flag(&spec, AST_URI_MARK)
736  && strchr(mark, *ptr))
737  && !(ast_test_flag(&spec, AST_URI_ALPHANUM)
738  && ((*ptr >= '0' && *ptr <= '9')
739  || (*ptr >= 'A' && *ptr <= 'Z')
740  || (*ptr >= 'a' && *ptr <= 'z')))
741  && !(ast_test_flag(&spec, AST_URI_SIP_USER_UNRESERVED)
742  && strchr(user_unreserved, *ptr))) {
743 
744  if (out - outbuf >= buflen - 3) {
745  break;
746  }
747  out += sprintf(out, "%%%02hhX", (unsigned char) *ptr);
748  } else {
749  *out = *ptr; /* Continue copying the string */
750  out++;
751  }
752  ptr++;
753  }
754 
755  if (buflen) {
756  *out = '\0';
757  }
758 
759  return outbuf;
760 }
char* ast_utils_which ( const char *  binary,
char *  fullpath,
size_t  fullpath_size 
)

Resolve a binary to a full pathname.

Parameters
binaryName of the executable to resolve
fullpathBuffer to hold the complete pathname
fullpath_sizeSize of fullpath
Return values
NULLbinary was not found or the environment variable PATH is not set
Returns
fullpath

Definition at line 2774 of file utils.c.

References ast_strdupa.

2775 {
2776  const char *envPATH = getenv("PATH");
2777  char *tpath, *path;
2778  struct stat unused;
2779  if (!envPATH) {
2780  return NULL;
2781  }
2782  tpath = ast_strdupa(envPATH);
2783  while ((path = strsep(&tpath, ":"))) {
2784  snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
2785  if (!stat(fullpath, &unused)) {
2786  return fullpath;
2787  }
2788  }
2789  return NULL;
2790 }
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int ast_xml_escape ( const char *  string,
char *  outbuf,
size_t  buflen 
)

Escape reserved characters for use in XML.

ast_xml_escape If outbuf is too short, the output string will be truncated. Regardless, the output will always be null terminated.

Parameters
stringString to be converted
outbufResulting encoded string
buflenSize of output buffer
Return values
0for success
-1if buflen is too short.

Definition at line 864 of file utils.c.

Referenced by ast_http_create_response().

865 {
866  char *dst = outbuf;
867  char *end = outbuf + buflen - 1; /* save one for the null terminator */
868 
869  /* Handle the case for the empty output buffer */
870  if (buflen == 0) {
871  return -1;
872  }
873 
874  /* Escaping rules from http://www.w3.org/TR/REC-xml/#syntax */
875  /* This also prevents partial entities at the end of a string */
876  while (*string && dst < end) {
877  const char *entity = NULL;
878  int len = 0;
879 
880  switch (*string) {
881  case '<':
882  entity = "&lt;";
883  len = 4;
884  break;
885  case '&':
886  entity = "&amp;";
887  len = 5;
888  break;
889  case '>':
890  /* necessary if ]]> is in the string; easier to escape them all */
891  entity = "&gt;";
892  len = 4;
893  break;
894  case '\'':
895  /* necessary in single-quoted strings; easier to escape them all */
896  entity = "&apos;";
897  len = 6;
898  break;
899  case '"':
900  /* necessary in double-quoted strings; easier to escape them all */
901  entity = "&quot;";
902  len = 6;
903  break;
904  default:
905  *dst++ = *string++;
906  break;
907  }
908 
909  if (entity) {
910  ast_assert(len == strlen(entity));
911  if (end - dst < len) {
912  /* no room for the entity; stop */
913  break;
914  }
915  /* just checked for length; strcpy is fine */
916  strcpy(dst, entity);
917  dst += len;
918  ++string;
919  }
920  }
921  /* Write null terminator */
922  *dst = '\0';
923  /* If any chars are left in string, return failure */
924  return *string == '\0' ? 0 : -1;
925 }

Variable Documentation

char escape_sequences[]
Initial value:
= {
'\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\'', '\"', '\?', '\0'
}

Definition at line 2022 of file utils.c.

char escape_sequences_map[]
static
Initial value:
= {
'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"', '?', '\0'
}

Definition at line 2030 of file utils.c.