Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
main/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"
Include dependency graph for main/utils.c:

Go to the source code of this file.

Data Structures

struct  lock_infos
 A list of each thread's lock info. More...
 
struct  thr_arg
 
struct  thr_lock_info
 Keep track of which locks a thread holds. More...
 

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 AST_MAX_LOCKS   64
 A reasonable maximum number of locks a thread would be holding ... More...
 
#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_lock_info (void)
 The thread storage key for per-thread lock info. More...
 
static void __init_thread_user_interface_tl (void)
 A thread local indicating whether the current thread is a user interface. More...
 
static void append_backtrace_information (struct ast_str **str, struct ast_bt *bt)
 
static void append_lock_information (struct ast_str **str, struct thr_lock_info *lock_info, int i)
 
int ast_background_stacksize (void)
 
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 More...
 
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_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...
 
struct ast_strast_dump_locks (void)
 Generate a lock dump equivalent to "core show locks". 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...
 
int ast_find_lock_info (void *lock_addr, char *filename, size_t filename_size, int *lineno, char *func, size_t func_size, char *mutex_name, size_t mutex_name_size)
 retrieve lock info for the specified mutex 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)
 
void ast_log_show_lock (void *this_lock_addr)
 log info for the current lock with ast_log(). More...
 
void ast_mark_lock_acquired (void *lock_addr)
 Mark the last lock as acquired. More...
 
void ast_mark_lock_failed (void *lock_addr)
 Mark the last lock as failed (trylock) 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_remove_lock_info (void *lock_addr, struct ast_bt *bt)
 remove lock info for the current thread More...
 
void ast_replace_subargument_delimiter (char *s)
 Replace '^' in a string with ','. More...
 
void ast_restore_lock_info (void *lock_addr)
 
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...
 
void ast_store_lock_info (enum ast_lock_type type, const char *filename, int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
 Store lock info for the current thread. 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...
 
void ast_suspend_lock_info (void *lock_addr)
 
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)
 
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. More...
 
struct timeval ast_tvsub (struct timeval a, struct timeval b)
 Returns the difference of two timevals a - b. More...
 
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 char * handle_show_locks (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void lock_info_destroy (void *data)
 Destroy a thread's lock info. More...
 
static const char * locktype2str (enum ast_lock_type type)
 
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 struct lock_infos lock_infos = { .first = NULL, .last = NULL, }
 
static ast_mutex_t lock_infos_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 Locked when accessing the lock_infos list. More...
 
static ast_mutex_t randomlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static struct ast_threadstorage thread_lock_info = { .once = PTHREAD_ONCE_INIT , .key_init = __init_thread_lock_info , .custom_init = NULL , }
 
static struct ast_threadstorage thread_user_interface_tl = { .once = PTHREAD_ONCE_INIT , .key_init = __init_thread_user_interface_tl , .custom_init = NULL , }
 
static struct ast_cli_entry utils_cli []
 

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 main/utils.c.

Macro Definition Documentation

◆ AST_API_MODULE [1/7]

#define AST_API_MODULE   /* ensure that inlinable API functions will be built in lock.h if required */

Definition at line 70 of file main/utils.c.

◆ AST_API_MODULE [2/7]

#define AST_API_MODULE   /* ensure that inlinable API functions will be built in this module if required */

Definition at line 70 of file main/utils.c.

◆ AST_API_MODULE [3/7]

#define AST_API_MODULE   /* ensure that inlinable API functions will be built in this module if required */

Definition at line 70 of file main/utils.c.

◆ AST_API_MODULE [4/7]

#define AST_API_MODULE   /* ensure that inlinable API functions will be built in this module if required */

Definition at line 70 of file main/utils.c.

◆ AST_API_MODULE [5/7]

#define AST_API_MODULE

Definition at line 70 of file main/utils.c.

◆ AST_API_MODULE [6/7]

#define AST_API_MODULE

Definition at line 70 of file main/utils.c.

◆ AST_API_MODULE [7/7]

#define AST_API_MODULE

Definition at line 70 of file main/utils.c.

◆ AST_MAX_LOCKS

#define AST_MAX_LOCKS   64

A reasonable maximum number of locks a thread would be holding ...

Definition at line 802 of file main/utils.c.

Referenced by ast_store_lock_info().

◆ ONE_MILLION

#define ONE_MILLION   1000000

Definition at line 1985 of file main/utils.c.

Referenced by ast_tvadd(), ast_tvsub(), and tvfix().

Function Documentation

◆ __ast_assert_failed()

void DO_CRASH_NORETURN __ast_assert_failed ( int  condition,
const char *  condition_str,
const char *  file,
int  line,
const char *  function 
)

Definition at line 2564 of file main/utils.c.

References __LOG_ERROR, ast_do_crash(), ast_log, and ast_log_backtrace().

Referenced by __ao2_container_clone(), __ao2_iterator_next(), __ao2_link(), __ao2_ref(), _ast_assert(), internal_ao2_traverse(), and log_bad_ao2().

2565 {
2566  /*
2567  * Attempt to put it into the logger, but hope that at least
2568  * someone saw the message on stderr ...
2569  */
2570  fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
2571  condition_str, condition, line, function, file);
2572  ast_log(__LOG_ERROR, file, line, function, "FRACK!, Failed assertion %s (%d)\n",
2573  condition_str, condition);
2574 
2575  /* Generate a backtrace for the assert */
2577 
2578  /*
2579  * Give the logger a chance to get the message out, just in case
2580  * we abort(), or Asterisk crashes due to whatever problem just
2581  * happened after we exit ast_assert().
2582  */
2583  usleep(1);
2584  ast_do_crash();
2585 }
#define __LOG_ERROR
Definition: logger.h:284
void ast_log_backtrace(void)
Log a backtrace of the current thread&#39;s execution stack to the Asterisk log.
Definition: logger.c:2158
#define ast_log
Definition: astobj2.c:42
void DO_CRASH_NORETURN ast_do_crash(void)
Force a crash if DO_CRASH is defined.
Definition: main/utils.c:2552

◆ __ast_fd_set_flags()

int __ast_fd_set_flags ( int  fd,
int  flags,
enum ast_fd_flag_operation  op,
const char *  file,
int  lineno,
const char *  function 
)

Definition at line 2898 of file main/utils.c.

References __LOG_ERROR, ast_assert, AST_FD_FLAG_CLEAR, AST_FD_FLAG_SET, ast_fd_set_flags, ast_log, ast_pipe_nonblock, ast_socket_nonblock, errno, and thr_lock_info::type.

2900 {
2901  int f;
2902 
2903  f = fcntl(fd, F_GETFL);
2904  if (f == -1) {
2905  ast_log(__LOG_ERROR, file, lineno, function,
2906  "Failed to get fcntl() flags for file descriptor: %s\n", strerror(errno));
2907  return -1;
2908  }
2909 
2910  switch (op) {
2911  case AST_FD_FLAG_SET:
2912  if ((f & flags) == flags) {
2913  /* There is nothing to set */
2914  return 0;
2915  }
2916  f |= flags;
2917  break;
2918  case AST_FD_FLAG_CLEAR:
2919  if (!(f & flags)) {
2920  /* There is nothing to clear */
2921  return 0;
2922  }
2923  f &= ~flags;
2924  break;
2925  default:
2926  ast_assert(0);
2927  break;
2928  }
2929 
2930  f = fcntl(fd, F_SETFL, f);
2931  if (f == -1) {
2932  ast_log(__LOG_ERROR, file, lineno, function,
2933  "Failed to set fcntl() flags for file descriptor: %s\n", strerror(errno));
2934  return -1;
2935  }
2936 
2937  return 0;
2938 }
#define ast_assert(a)
Definition: utils.h:695
#define __LOG_ERROR
Definition: logger.h:284
#define ast_log
Definition: astobj2.c:42
int errno

◆ __init_inet_ntoa_buf()

static void __init_inet_ntoa_buf ( void  )
static

Definition at line 83 of file main/utils.c.

100 {

◆ __init_thread_lock_info()

static void __init_thread_lock_info ( void  )
static

The thread storage key for per-thread lock info.

Definition at line 902 of file main/utils.c.

907 {

◆ __init_thread_user_interface_tl()

static void __init_thread_user_interface_tl ( void  )
static

A thread local indicating whether the current thread is a user interface.

Definition at line 2979 of file main/utils.c.

2982 {

◆ append_backtrace_information()

static void append_backtrace_information ( struct ast_str **  str,
struct ast_bt bt 
)
static

Definition at line 1147 of file main/utils.c.

References ast_bt::addresses, ast_bt_free_symbols, ast_bt_get_symbols, ast_str_append(), AST_VECTOR_GET, AST_VECTOR_SIZE, and ast_bt::num_frames.

Referenced by append_lock_information().

1148 {
1149  struct ast_vector_string *symbols;
1150  int num_frames;
1151 
1152  if (!bt) {
1153  ast_str_append(str, 0, "\tNo backtrace to print\n");
1154  return;
1155  }
1156 
1157  /* store frame count locally to avoid the memory corruption that
1158  * sometimes happens on virtualized CentOS 6.x systems */
1159  num_frames = bt->num_frames;
1160  if ((symbols = ast_bt_get_symbols(bt->addresses, num_frames))) {
1161  int frame_iterator;
1162 
1163  for (frame_iterator = 1; frame_iterator < AST_VECTOR_SIZE(symbols); ++frame_iterator) {
1164  ast_str_append(str, 0, "\t%s\n", AST_VECTOR_GET(symbols, frame_iterator));
1165  }
1166 
1167  ast_bt_free_symbols(symbols);
1168  } else {
1169  ast_str_append(str, 0, "\tCouldn't retrieve backtrace symbols\n");
1170  }
1171 }
#define ast_bt_free_symbols(string_vector)
Definition: backtrace.h:42
#define ast_bt_get_symbols(addresses, num_frames)
Definition: backtrace.h:41
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
void * addresses[AST_MAX_BT_FRAMES]
Definition: backtrace.h:52
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
int num_frames
Definition: backtrace.h:54
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ append_lock_information()

static void append_lock_information ( struct ast_str **  str,
struct thr_lock_info lock_info,
int  i 
)
static

Definition at line 1174 of file main/utils.c.

References append_backtrace_information(), AST_MUTEX, ast_reentrancy_lock(), ast_reentrancy_unlock(), ast_str_append(), thr_lock_info::backtrace, ast_lock_track::file, thr_lock_info::file, ast_lock_track::func, thr_lock_info::func, thr_lock_info::line_num, ast_lock_track::lineno, thr_lock_info::lock, thr_lock_info::lock_addr, thr_lock_info::lock_name, thr_lock_info::locks, locktype2str(), thr_lock_info::pending, ast_lock_track::reentrancy, thr_lock_info::suspended, thr_lock_info::times_locked, ast_mutex_info::track, and thr_lock_info::type.

Referenced by ast_dump_locks(), and ast_log_show_lock().

1175 {
1176  int j;
1177  ast_mutex_t *lock;
1178  struct ast_lock_track *lt;
1179 
1180  ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d%s)\n",
1181  lock_info->locks[i].pending > 0 ? "Waiting for " :
1182  lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
1183  lock_info->locks[i].file,
1184  locktype2str(lock_info->locks[i].type),
1185  lock_info->locks[i].line_num,
1186  lock_info->locks[i].func, lock_info->locks[i].lock_name,
1187  lock_info->locks[i].lock_addr,
1188  lock_info->locks[i].times_locked,
1189  lock_info->locks[i].suspended ? " - suspended" : "");
1190 #ifdef HAVE_BKTR
1191  append_backtrace_information(str, lock_info->locks[i].backtrace);
1192 #endif
1193 
1194  if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
1195  return;
1196 
1197  /* We only have further details for mutexes right now */
1198  if (lock_info->locks[i].type != AST_MUTEX)
1199  return;
1200 
1201  lock = lock_info->locks[i].lock_addr;
1202  lt = lock->track;
1203  ast_reentrancy_lock(lt);
1204  for (j = 0; *str && j < lt->reentrancy; j++) {
1205  ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
1206  lt->file[j], lt->lineno[j], lt->func[j]);
1207  }
1209 }
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
const char * file[AST_MAX_REENTRANCY]
Definition: lock.h:112
const char * lock_name
Definition: main/utils.c:825
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
int reentrancy
Definition: lock.h:114
int lineno[AST_MAX_REENTRANCY]
Definition: lock.h:113
void * lock_addr
Definition: main/utils.c:826
struct ast_lock_track * track
Definition: lock.h:146
Lock tracking information.
Definition: lock.h:111
ast_mutex_t lock
Definition: app_meetme.c:1091
struct ast_bt * backtrace
Definition: main/utils.c:835
enum ast_lock_type type
Definition: main/utils.c:829
const char * func
Definition: main/utils.c:824
static void ast_reentrancy_lock(struct ast_lock_track *lt)
Definition: lock.h:443
const char * file
Definition: main/utils.c:823
const char * func[AST_MAX_REENTRANCY]
Definition: lock.h:115
static void ast_reentrancy_unlock(struct ast_lock_track *lt)
Definition: lock.h:454
static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
Definition: main/utils.c:1147
static const char * locktype2str(enum ast_lock_type type)
Definition: main/utils.c:1132
Structure for mutex and tracking information.
Definition: lock.h:135

◆ ast_background_stacksize()

int ast_background_stacksize ( void  )

Definition at line 1437 of file main/utils.c.

References AST_STACKSIZE, and AST_STACKSIZE_LOW.

1438 {
1439 #if !defined(LOW_MEMORY)
1440  return AST_STACKSIZE;
1441 #else
1442  return AST_STACKSIZE_LOW;
1443 #endif
1444 }
#define AST_STACKSIZE
Definition: utils.h:540
#define AST_STACKSIZE_LOW
Definition: utils.h:541

◆ ast_base64decode()

int ast_base64decode ( unsigned char *  dst,
const char *  src,
int  max 
)

decode BASE64 encoded text

Decode data from base64.

Definition at line 294 of file main/utils.c.

References b2a.

Referenced by action_messagesend(), aes_helper(), ast_base64decode_string(), ast_check_signature(), ast_http_get_auth(), AST_TEST_DEFINE(), base64_helper(), crypto_init_keys(), custom_presence_callback(), osp_validate_token(), presence_write(), and res_sdp_crypto_parse_offer().

295 {
296  int cnt = 0;
297  unsigned int byte = 0;
298  unsigned int bits = 0;
299  int incnt = 0;
300  while(*src && *src != '=' && (cnt < max)) {
301  /* Shift in 6 bits of input */
302  byte <<= 6;
303  byte |= (b2a[(int)(*src)]) & 0x3f;
304  bits += 6;
305  src++;
306  incnt++;
307  /* If we have at least 8 bits left over, take that character
308  off the top */
309  if (bits >= 8) {
310  bits -= 8;
311  *dst = (byte >> bits) & 0xff;
312  dst++;
313  cnt++;
314  }
315  }
316  /* Don't worry about left over bits, they're extra anyway */
317  return cnt;
318 }
static char b2a[256]
Definition: main/utils.c:80
#define max(a, b)
Definition: f2c.h:198

◆ ast_base64decode_string()

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 321 of file main/utils.c.

References ast_base64decode(), ast_malloc, ast_strlen_zero, and NULL.

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

◆ ast_base64encode()

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 404 of file main/utils.c.

References ast_base64encode_full().

Referenced by aes_helper(), ast_base64encode_string(), ast_sign(), AST_TEST_DEFINE(), base64_helper(), build_secret(), crypto_init_keys(), osp_check_destination(), presence_read(), websocket_client_create_key(), websocket_combine_key(), and xmpp_client_authenticate_sasl().

405 {
406  return ast_base64encode_full(dst, src, srclen, max, 0);
407 }
int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
encode text to BASE64 coding
Definition: main/utils.c:353
#define max(a, b)
Definition: f2c.h:198

◆ ast_base64encode_full()

int ast_base64encode_full ( char *  dst,
const unsigned char *  src,
int  srclen,
int  max,
int  linebreaks 
)

encode text to BASE64 coding

Definition at line 353 of file main/utils.c.

References base64, and max.

Referenced by ast_base64encode().

354 {
355  int cnt = 0;
356  int col = 0;
357  unsigned int byte = 0;
358  int bits = 0;
359  int cntin = 0;
360  /* Reserve space for null byte at end of string */
361  max--;
362  while ((cntin < srclen) && (cnt < max)) {
363  byte <<= 8;
364  byte |= *(src++);
365  bits += 8;
366  cntin++;
367  if ((bits == 24) && (cnt + 4 <= max)) {
368  *dst++ = base64[(byte >> 18) & 0x3f];
369  *dst++ = base64[(byte >> 12) & 0x3f];
370  *dst++ = base64[(byte >> 6) & 0x3f];
371  *dst++ = base64[byte & 0x3f];
372  cnt += 4;
373  col += 4;
374  bits = 0;
375  byte = 0;
376  }
377  if (linebreaks && (cnt < max) && (col == 64)) {
378  *dst++ = '\n';
379  cnt++;
380  col = 0;
381  }
382  }
383  if (bits && (cnt + 4 <= max)) {
384  /* Add one last character for the remaining bits,
385  padding the rest with 0 */
386  byte <<= 24 - bits;
387  *dst++ = base64[(byte >> 18) & 0x3f];
388  *dst++ = base64[(byte >> 12) & 0x3f];
389  if (bits == 16)
390  *dst++ = base64[(byte >> 6) & 0x3f];
391  else
392  *dst++ = '=';
393  *dst++ = '=';
394  cnt += 4;
395  }
396  if (linebreaks && (cnt < max)) {
397  *dst++ = '\n';
398  cnt++;
399  }
400  *dst = '\0';
401  return cnt;
402 }
static char base64[64]
Definition: main/utils.c:78
#define max(a, b)
Definition: f2c.h:198

◆ ast_base64encode_string()

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 410 of file main/utils.c.

References ast_base64encode(), ast_calloc, ast_strlen_zero, and NULL.

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

◆ ast_base64url_decode()

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 427 of file main/utils.c.

References b2a_url.

Referenced by ast_base64url_decode_string(), and stir_shaken_verify_signature().

428 {
429  int cnt = 0;
430  unsigned int byte = 0;
431  unsigned int bits = 0;
432 
433  while (*src && (cnt < max)) {
434  byte <<= 6;
435  byte |= (b2a_url[(int)(*src)]) & 0x3f;
436  bits += 6;
437  src++;
438  if (bits >= 8) {
439  bits -= 8;
440  *dst = (byte >> bits) & 0xff;
441  dst++;
442  cnt++;
443  }
444  }
445  return cnt;
446 }
static char b2a_url[256]
Definition: main/utils.c:81
#define max(a, b)
Definition: f2c.h:198

◆ ast_base64url_decode_string()

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
Decodedstring on success

Definition at line 448 of file main/utils.c.

References ast_base64url_decode(), ast_malloc, ast_strlen_zero, and NULL.

Referenced by stir_shaken_incoming_request().

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

◆ ast_base64url_encode()

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 516 of file main/utils.c.

References ast_base64url_encode_full().

Referenced by ast_base64url_encode_string(), and stir_shaken_sign().

517 {
518  return ast_base64url_encode_full(dst, src, srclen, max, 0);
519 }
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: main/utils.c:469
#define max(a, b)
Definition: f2c.h:198

◆ ast_base64url_encode_full()

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 469 of file main/utils.c.

References base64url, and max.

Referenced by ast_base64url_encode().

470 {
471  int cnt = 0;
472  int col = 0;
473  unsigned int byte = 0;
474  int bits = 0;
475  int cntin = 0;
476 
477  max--;
478  while ((cntin < srclen) && (cnt < max)) {
479  byte <<= 8;
480  byte |= *(src++);
481  bits += 8;
482  cntin++;
483  if ((bits == 24) && (cnt + 4 <= max)) {
484  *dst++ = base64url[(byte >> 18) & 0x3f];
485  *dst++ = base64url[(byte >> 12) & 0x3f];
486  *dst++ = base64url[(byte >> 6) & 0x3f];
487  *dst++ = base64url[(byte) & 0x3f];
488  cnt += 4;
489  col += 4;
490  bits = 0;
491  byte = 0;
492  }
493  if (linebreaks && (cnt < max) && (col == 64)) {
494  *dst++ = '\n';
495  cnt++;
496  col = 0;
497  }
498  }
499  if (bits && (cnt + 4 <= max)) {
500  byte <<= 24 - bits;
501  *dst++ = base64url[(byte >> 18) & 0x3f];
502  *dst++ = base64url[(byte >> 12) & 0x3f];
503  if (bits == 16) {
504  *dst++ = base64url[(byte >> 6) & 0x3f];
505  }
506  cnt += 4;
507  }
508  if (linebreaks && (cnt < max)) {
509  *dst++ = '\n';
510  cnt++;
511  }
512  *dst = '\0';
513  return cnt;
514 }
static char base64url[64]
Definition: main/utils.c:79
#define max(a, b)
Definition: f2c.h:198

◆ ast_base64url_encode_string()

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
Encodedstring on success

Definition at line 521 of file main/utils.c.

References ast_base64url_encode(), ast_malloc, ast_strlen_zero, and NULL.

Referenced by add_identity_header().

522 {
523  size_t encoded_len;
524  char *encoded_string;
525 
526  if (ast_strlen_zero(src)) {
527  return NULL;
528  }
529 
530  encoded_len = ((strlen(src) * 4 / 3 + 3) & ~3) + 1;
531  encoded_string = ast_malloc(encoded_len);
532 
533  ast_base64url_encode(encoded_string, (const unsigned char *)src, strlen(src), encoded_len);
534 
535  return encoded_string;
536 }
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
int ast_base64url_encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64 URL.
Definition: main/utils.c:516

◆ ast_build_string()

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 1919 of file main/utils.c.

References ast_build_string_va(), and result.

Referenced by ast_fax_caps_to_str(), generate_filenames_string(), handle_speechrecognize(), pp_each_extension_helper(), and vm_allocate_dh().

1920 {
1921  va_list ap;
1922  int result;
1923 
1924  va_start(ap, fmt);
1925  result = ast_build_string_va(buffer, space, fmt, ap);
1926  va_end(ap);
1927 
1928  return result;
1929 }
int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
Build a string in a buffer, designed to be called repeatedly.
Definition: main/utils.c:1900
static PGresult * result
Definition: cel_pgsql.c:88

◆ ast_build_string_va()

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.

Returns
0 on success, non-zero on 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 1900 of file main/utils.c.

References result.

Referenced by ast_build_string().

1901 {
1902  int result;
1903 
1904  if (!buffer || !*buffer || !space || !*space)
1905  return -1;
1906 
1907  result = vsnprintf(*buffer, *space, fmt, ap);
1908 
1909  if (result < 0)
1910  return -1;
1911  else if (result > *space)
1912  result = *space;
1913 
1914  *buffer += result;
1915  *space -= result;
1916  return 0;
1917 }
static PGresult * result
Definition: cel_pgsql.c:88

◆ ast_carefulwrite()

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 1592 of file main/utils.c.

References ast_debug, ast_log, ast_tvdiff_ms(), ast_tvnow(), errno, LOG_ERROR, and wait_for_output().

Referenced by ast_agi_send(), AST_VECTOR(), and cleanup_module().

1593 {
1594  struct timeval start = ast_tvnow();
1595  int res = 0;
1596  int elapsed = 0;
1597 
1598  while (len) {
1599  if (wait_for_output(fd, timeoutms - elapsed)) {
1600  return -1;
1601  }
1602 
1603  res = write(fd, s, len);
1604 
1605  if (res < 0 && errno != EAGAIN && errno != EINTR) {
1606  /* fatal error from write() */
1607  if (errno == EPIPE) {
1608 #ifndef STANDALONE
1609  ast_debug(1, "write() failed due to reading end being closed: %s\n", strerror(errno));
1610 #endif
1611  } else {
1612  ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
1613  }
1614  return -1;
1615  }
1616 
1617  if (res < 0) {
1618  /* It was an acceptable error */
1619  res = 0;
1620  }
1621 
1622  /* Update how much data we have left to write */
1623  len -= res;
1624  s += res;
1625  res = 0;
1626 
1627  elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1628  if (elapsed >= timeoutms) {
1629  /* We've taken too long to write
1630  * This is only an error condition if we haven't finished writing. */
1631  res = len ? -1 : 0;
1632  break;
1633  }
1634  }
1635 
1636  return res;
1637 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
static int wait_for_output(int fd, int timeoutms)
Definition: main/utils.c:1539

◆ ast_check_ipv6()

int ast_check_ipv6 ( void  )

Test that an OS supports IPv6 Networking.

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

Definition at line 2540 of file main/utils.c.

Referenced by load_module().

2541 {
2542  int udp6_socket = socket(AF_INET6, SOCK_DGRAM, 0);
2543 
2544  if (udp6_socket < 0) {
2545  return 0;
2546  }
2547 
2548  close(udp6_socket);
2549  return 1;
2550 }

◆ ast_compare_versions()

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.
Returns
<0 if version 1 < version 2.
=0 if version 1 = version 2.
>0 if version 1 > version 2.

Definition at line 2872 of file main/utils.c.

Referenced by transport_apply().

2873 {
2874  unsigned int major[2] = { 0 };
2875  unsigned int minor[2] = { 0 };
2876  unsigned int patch[2] = { 0 };
2877  unsigned int extra[2] = { 0 };
2878  int res;
2879 
2880  sscanf(version1, "%u.%u.%u.%u", &major[0], &minor[0], &patch[0], &extra[0]);
2881  sscanf(version2, "%u.%u.%u.%u", &major[1], &minor[1], &patch[1], &extra[1]);
2882 
2883  res = major[0] - major[1];
2884  if (res) {
2885  return res;
2886  }
2887  res = minor[0] - minor[1];
2888  if (res) {
2889  return res;
2890  }
2891  res = patch[0] - patch[1];
2892  if (res) {
2893  return res;
2894  }
2895  return extra[0] - extra[1];
2896 }

◆ ast_do_crash()

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.
Returns
Nothing

Definition at line 2552 of file main/utils.c.

Referenced by __ast_assert_failed(), _ast_assert(), ast_optional_api_use(), optional_api_create(), optional_api_user_create(), and sip_route_process_header().

2553 {
2554 #if defined(DO_CRASH)
2555  abort();
2556  /*
2557  * Just in case abort() doesn't work or something else super
2558  * silly, and for Qwell's amusement.
2559  */
2560  *((int *) 0) = 0;
2561 #endif /* defined(DO_CRASH) */
2562 }

◆ ast_dump_locks()

struct ast_str* ast_dump_locks ( void  )

Generate a lock dump equivalent to "core show locks".

The lock dump generated is generally too large to be output by a single ast_verbose/log/debug/etc. call. Only ast_cli() handles it properly without changing BUFSIZ in logger.c.

Note: This must be ast_free()d when you're done with it.

Return values
Anast_str containing the lock dump
NULLon error
Since
12

Definition at line 1264 of file main/utils.c.

References append_lock_information(), ast_get_version(), AST_LIST_TRAVERSE, ast_str_append(), ast_str_create, thr_lock_info::lock, lock_info, lock_infos_lock, thr_lock_info::locks, thr_lock_info::lwp, ast_mutex_info::mutex, NULL, thr_lock_info::num_locks, pthread_mutex_lock, pthread_mutex_unlock, str, thr_lock_info::suspended, thr_lock_info::thread_id, and thr_lock_info::thread_name.

Referenced by handle_show_locks().

1265 {
1266 #if !defined(LOW_MEMORY)
1267  struct thr_lock_info *lock_info;
1268  struct ast_str *str;
1269 
1270  if (!(str = ast_str_create(4096))) {
1271  return NULL;
1272  }
1273 
1274  ast_str_append(&str, 0, "\n"
1275  "=======================================================================\n"
1276  "=== %s\n"
1277  "=== Currently Held Locks\n"
1278  "=======================================================================\n"
1279  "===\n"
1280  "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n"
1281  "===\n", ast_get_version());
1282 
1283  if (!str) {
1284  return NULL;
1285  }
1286 
1288  AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
1289  int i;
1290  int header_printed = 0;
1291  pthread_mutex_lock(&lock_info->lock);
1292  for (i = 0; str && i < lock_info->num_locks; i++) {
1293  /* Don't show suspended locks */
1294  if (lock_info->locks[i].suspended) {
1295  continue;
1296  }
1297 
1298  if (!header_printed) {
1299  if (lock_info->lwp != -1) {
1300  ast_str_append(&str, 0, "=== Thread ID: 0x%lx LWP:%d (%s)\n",
1301  (long unsigned) lock_info->thread_id, lock_info->lwp, lock_info->thread_name);
1302  } else {
1303  ast_str_append(&str, 0, "=== Thread ID: 0x%lx (%s)\n",
1304  (long unsigned) lock_info->thread_id, lock_info->thread_name);
1305  }
1306  header_printed = 1;
1307  }
1308 
1309  append_lock_information(&str, lock_info, i);
1310  }
1311  pthread_mutex_unlock(&lock_info->lock);
1312  if (!str) {
1313  break;
1314  }
1315  if (header_printed) {
1316  ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
1317  "===\n");
1318  }
1319  if (!str) {
1320  break;
1321  }
1322  }
1324 
1325  if (!str) {
1326  return NULL;
1327  }
1328 
1329  ast_str_append(&str, 0, "=======================================================================\n"
1330  "\n");
1331 
1332  return str;
1333 #else /* if defined(LOW_MEMORY) */
1334  return NULL;
1335 #endif
1336 }
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
const char * ast_get_version(void)
Retrieve the Asterisk version string.
Definition: version.c:16
static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
Definition: main/utils.c:1174
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
unsigned int num_locks
Definition: main/utils.c:841
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
static ast_mutex_t lock_infos_lock
Locked when accessing the lock_infos list.
Definition: main/utils.c:853
#define pthread_mutex_lock
Definition: lock.h:623
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
pthread_mutex_t lock
Definition: main/utils.c:846
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
pthread_t thread_id
Definition: main/utils.c:818
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
const char * thread_name
Definition: main/utils.c:820
A list of each thread&#39;s lock info.
Definition: main/utils.c:857
Keep track of which locks a thread holds.
Definition: main/utils.c:816
pthread_mutex_t mutex
Definition: lock.h:136
Definition: search.h:40
#define pthread_mutex_unlock
Definition: lock.h:624
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ ast_eid_cmp()

int ast_eid_cmp ( const struct ast_eid eid1,
const struct ast_eid eid2 
)

◆ ast_eid_is_empty()

int ast_eid_is_empty ( const struct ast_eid eid)

Check if EID is empty.

Returns
1 if the EID is empty, zero otherwise
Since
13.12.0

Definition at line 2847 of file main/utils.c.

Referenced by load_module(), and set_config().

2848 {
2849  struct ast_eid empty_eid;
2850 
2851  memset(&empty_eid, 0, sizeof(empty_eid));
2852  return memcmp(eid, &empty_eid, sizeof(empty_eid)) ? 0 : 1;
2853 }
An Entity ID is essentially a MAC address, brief and unique.
Definition: utils.h:786
static dundi_eid empty_eid
Definition: pbx_dundi.c:212

◆ ast_eid_to_str()

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 2587 of file main/utils.c.

References ast_debug, ast_free, ast_log, ast_malloc, ast_set_default_eid(), buf, ast_eid::eid, LOG_WARNING, and NULL.

Referenced by app_send(), append_transaction(), ast_ari_asterisk_get_info(), ast_ari_asterisk_ping(), ast_set_default_eid(), ast_str_retrieve_variable(), AST_TEST_DEFINE(), asterisk_publication_send_refresh(), asterisk_publisher_devstate_cb(), asterisk_publisher_mwistate_cb(), bridges_scrape_cb(), build_peer(), build_transactions(), cache_lookup(), cache_lookup_internal(), channels_scrape_cb(), check_key(), complete_peer_helper(), cpg_deliver_cb(), destroy_trans(), do_autokill(), do_register(), do_register_expire(), dump_answer(), dump_eid(), dundi_answer_entity(), dundi_lookup_internal(), dundi_lookup_local(), dundi_lookup_thread(), dundi_precache_thread(), dundi_prop_precache(), dundi_query_thread(), dundi_send(), dundi_show_cache(), dundi_show_entityid(), dundi_show_hints(), dundi_show_peer(), dundi_show_peers(), dundi_show_requests(), endpoints_scrape_cb(), handle_command_response(), handle_show_settings(), populate_addr(), prometheus_config_post_apply(), publish_cluster_discovery_to_stasis_full(), publish_device_state_to_stasis(), publish_mwi_to_stasis(), publish_to_corosync(), register_request(), registry_message_cb(), update_key(), xmpp_pubsub_publish_device_state(), and xmpp_pubsub_publish_mwi().

2588 {
2589  int x;
2590  char *os = s;
2591  if (maxlen < 18) {
2592  if (s && (maxlen > 0)) {
2593  *s = '\0';
2594  }
2595  } else {
2596  for (x = 0; x < 5; x++) {
2597  sprintf(s, "%02hhx:", eid->eid[x]);
2598  s += 3;
2599  }
2600  sprintf(s, "%02hhx", eid->eid[5]);
2601  }
2602  return os;
2603 }
unsigned char eid[6]
Definition: utils.h:787

◆ ast_enable_packet_fragmentation()

void ast_enable_packet_fragmentation ( int  sock)

Disable PMTU discovery on a socket.

Parameters
sockThe socket to manipulate
Returns
Nothing

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 2221 of file main/utils.c.

References ast_log, and LOG_WARNING.

Referenced by ast_netsock_bindaddr(), and reload_config().

2222 {
2223 #if defined(HAVE_IP_MTU_DISCOVER)
2224  int val = IP_PMTUDISC_DONT;
2225 
2226  if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
2227  ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
2228 #endif /* HAVE_IP_MTU_DISCOVER */
2229 }
Definition: ast_expr2.c:325
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42

◆ ast_escape()

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 1786 of file main/utils.c.

References ast_copy_string(), ast_strlen_zero, c, and escape_sequences.

Referenced by ast_escape_alloc().

1787 {
1788  char *p;
1789  char *c;
1790 
1791  if (!dest || !size) {
1792  return dest;
1793  }
1794  if (ast_strlen_zero(s)) {
1795  *dest = '\0';
1796  return dest;
1797  }
1798 
1799  if (ast_strlen_zero(to_escape)) {
1800  ast_copy_string(dest, s, size);
1801  return dest;
1802  }
1803 
1804  for (p = dest; *s && --size; ++s, ++p) {
1805  /* If in the list of characters to escape then escape it */
1806  if (strchr(to_escape, *s)) {
1807  if (!--size) {
1808  /* Not enough room left for the escape sequence. */
1809  break;
1810  }
1811 
1812  /*
1813  * See if the character to escape is part of the standard escape
1814  * sequences. If so we'll have to use its mapped counterpart
1815  * otherwise just use the current character.
1816  */
1817  c = strchr(escape_sequences, *s);
1818  *p++ = '\\';
1819  *p = c ? escape_sequences_map[c - escape_sequences] : *s;
1820  } else {
1821  *p = *s;
1822  }
1823  }
1824  *p = '\0';
1825 
1826  return dest;
1827 }
static struct test_val c
char escape_sequences[]
Definition: main/utils.c:1774
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char escape_sequences_map[]
Definition: main/utils.c:1782
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ ast_escape_alloc()

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 1884 of file main/utils.c.

References ast_escape(), and escape_alloc().

1885 {
1886  size_t size = 0;
1887  char *dest = escape_alloc(s, &size);
1888 
1889  return ast_escape(dest, s, size, to_escape);
1890 }
static char * escape_alloc(const char *s, size_t *size)
Definition: main/utils.c:1870
char * ast_escape(char *dest, const char *s, size_t size, const char *to_escape)
Escape the &#39;to_escape&#39; characters in the given string.
Definition: main/utils.c:1786

◆ ast_escape_c()

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 1829 of file main/utils.c.

References ast_strlen_zero, c, and escape_sequences.

Referenced by ast_escape_c_alloc().

1830 {
1831  /*
1832  * Note - This is an optimized version of ast_escape. When looking only
1833  * for escape_sequences a couple of checks used in the generic case can
1834  * be left out thus making it slightly more efficient.
1835  */
1836  char *p;
1837  char *c;
1838 
1839  if (!dest || !size) {
1840  return dest;
1841  }
1842  if (ast_strlen_zero(s)) {
1843  *dest = '\0';
1844  return dest;
1845  }
1846 
1847  for (p = dest; *s && --size; ++s, ++p) {
1848  /*
1849  * See if the character to escape is part of the standard escape
1850  * sequences. If so use its mapped counterpart.
1851  */
1852  c = strchr(escape_sequences, *s);
1853  if (c) {
1854  if (!--size) {
1855  /* Not enough room left for the escape sequence. */
1856  break;
1857  }
1858 
1859  *p++ = '\\';
1861  } else {
1862  *p = *s;
1863  }
1864  }
1865  *p = '\0';
1866 
1867  return dest;
1868 }
static struct test_val c
char escape_sequences[]
Definition: main/utils.c:1774
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char escape_sequences_map[]
Definition: main/utils.c:1782

◆ ast_escape_c_alloc()

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 1892 of file main/utils.c.

References ast_escape_c(), and escape_alloc().

Referenced by ast_manager_build_channel_state_string_prefix(), channel_new_callerid(), presence_state_to_ami(), and varset_to_ami().

1893 {
1894  size_t size = 0;
1895  char *dest = escape_alloc(s, &size);
1896 
1897  return ast_escape_c(dest, s, size);
1898 }
char * ast_escape_c(char *dest, const char *s, size_t size)
Escape standard &#39;C&#39; sequences in the given string.
Definition: main/utils.c:1829
static char * escape_alloc(const char *s, size_t *size)
Definition: main/utils.c:1870

◆ ast_escape_quoted()

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 635 of file main/utils.c.

References out, and string.

Referenced by add_diversion(), add_rpid(), ast_callerid_merge(), ast_sip_modify_id_header(), AST_TEST_DEFINE(), channel_read_pjsip(), create_new_id_hdr(), initreqprep(), print_escaped_uri(), and receive_message().

636 {
637  const char *ptr = string;
638  char *out = outbuf;
639  char *allow = "\t\v !"; /* allow LWS (minus \r and \n) and "!" */
640 
641  while (*ptr && out - outbuf < buflen - 1) {
642  if (!(strchr(allow, *ptr))
643  && !(*ptr >= '#' && *ptr <= '[') /* %x23 - %x5b */
644  && !(*ptr >= ']' && *ptr <= '~') /* %x5d - %x7e */
645  && !((unsigned char) *ptr > 0x7f)) { /* UTF8-nonascii */
646 
647  if (out - outbuf >= buflen - 2) {
648  break;
649  }
650  out += sprintf(out, "\\%c", (unsigned char) *ptr);
651  } else {
652  *out = *ptr;
653  out++;
654  }
655  ptr++;
656  }
657 
658  if (buflen) {
659  *out = '\0';
660  }
661 
662  return outbuf;
663 }
const char * string
Definition: presencestate.c:71
FILE * out
Definition: utils/frame.c:33

◆ ast_escape_semicolons()

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 665 of file main/utils.c.

References ast_assert, NULL, out, and string.

Referenced by ast_config_text_file_save2(), handle_cli_dialplan_save(), and test_semi().

666 {
667  const char *ptr = string;
668  char *out = outbuf;
669 
670  if (string == NULL || outbuf == NULL) {
671  ast_assert(string != NULL && outbuf != NULL);
672  return NULL;
673  }
674 
675  while (*ptr && out - outbuf < buflen - 1) {
676  if (*ptr == ';') {
677  if (out - outbuf >= buflen - 2) {
678  break;
679  }
680  strcpy(out, "\\;");
681  out += 2;
682  } else {
683  *out = *ptr;
684  out++;
685  }
686  ptr++;
687  }
688 
689  if (buflen) {
690  *out = '\0';
691  }
692 
693  return outbuf;
694 }
#define ast_assert(a)
Definition: utils.h:695
const char * string
Definition: presencestate.c:71
#define NULL
Definition: resample.c:96
FILE * out
Definition: utils/frame.c:33

◆ ast_false()

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
0if val is a NULL pointer.
-1if "true".
0otherwise.

Definition at line 1968 of file main/utils.c.

References ast_strlen_zero.

Referenced by acf_faxopt_write(), acf_transaction_write(), actual_load_config(), announce_user_count_all_handler(), aoc_cli_debug_enable(), bool_handler_fn(), boolflag_handler_fn(), build_peer(), build_user(), check_debug(), dahdi_set_dnd(), find_realtime(), function_ooh323_write(), handle_common_options(), handle_queue_set_member_ringinuse(), hook_write(), init_acf_query(), load_config(), manager_mute_mixmonitor(), manager_queue_member_ringinuse(), parking_feature_flag_cfg(), parse_empty_options(), parse_playtone(), prack_handler(), process_config(), process_dahdi(), process_echocancel(), read_pjproject_startup_options(), reload(), reload_config(), reload_single_member(), rt_handle_member_record(), rtp_reload(), run_agi(), set_config(), set_insecure_flags(), sip_parse_nat_option(), sla_build_trunk(), strings_to_mask(), and timers_handler().

1969 {
1970  if (ast_strlen_zero(s))
1971  return 0;
1972 
1973  /* Determine if this is a false value */
1974  if (!strcasecmp(s, "no") ||
1975  !strcasecmp(s, "false") ||
1976  !strcasecmp(s, "n") ||
1977  !strcasecmp(s, "f") ||
1978  !strcasecmp(s, "0") ||
1979  !strcasecmp(s, "off"))
1980  return -1;
1981 
1982  return 0;
1983 }
#define ast_strlen_zero(foo)
Definition: strings.h:52

◆ ast_file_is_readable()

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.
Returns
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 2855 of file main/utils.c.

Referenced by add_email_attachment(), ast_media_cache_retrieve(), ast_rtp_dtls_cfg_parse(), on_load_ca_file(), on_load_ca_path(), and transport_tls_file_handler().

2856 {
2857 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
2858 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
2859 #define eaccess euidaccess
2860 #endif
2861  return eaccess(filename, R_OK) == 0;
2862 #else
2863  int fd = open(filename, O_RDONLY | O_NONBLOCK);
2864  if (fd < 0) {
2865  return 0;
2866  }
2867  close(fd);
2868  return 1;
2869 #endif
2870 }

◆ ast_find_lock_info()

int ast_find_lock_info ( void *  lock_addr,
char *  filename,
size_t  filename_size,
int *  lineno,
char *  func,
size_t  func_size,
char *  mutex_name,
size_t  mutex_name_size 
)

retrieve lock info for the specified mutex

this gets called during deadlock avoidance, so that the information may be preserved as to what location originally acquired the lock.

Definition at line 995 of file main/utils.c.

References ast_copy_string(), ast_threadstorage_get(), thr_lock_info::file, thr_lock_info::func, thr_lock_info::line_num, thr_lock_info::lock, thr_lock_info::lock_addr, lock_info, thr_lock_info::lock_name, thr_lock_info::locks, thr_lock_info::num_locks, pthread_mutex_lock, pthread_mutex_unlock, and thread_lock_info.

996 {
997 #if !defined(LOW_MEMORY)
998  struct thr_lock_info *lock_info;
999  int i = 0;
1000 
1001  if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
1002  return -1;
1003 
1004  pthread_mutex_lock(&lock_info->lock);
1005 
1006  for (i = lock_info->num_locks - 1; i >= 0; i--) {
1007  if (lock_info->locks[i].lock_addr == lock_addr)
1008  break;
1009  }
1010 
1011  if (i == -1) {
1012  /* Lock not found :( */
1013  pthread_mutex_unlock(&lock_info->lock);
1014  return -1;
1015  }
1016 
1017  ast_copy_string(filename, lock_info->locks[i].file, filename_size);
1018  *lineno = lock_info->locks[i].line_num;
1019  ast_copy_string(func, lock_info->locks[i].func, func_size);
1020  ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
1021 
1022  pthread_mutex_unlock(&lock_info->lock);
1023 
1024  return 0;
1025 #else /* if defined(LOW_MEMORY) */
1026  return -1;
1027 #endif
1028 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
const char * lock_name
Definition: main/utils.c:825
static struct ast_threadstorage thread_lock_info
Definition: main/utils.c:902
unsigned int num_locks
Definition: main/utils.c:841
void * lock_addr
Definition: main/utils.c:826
#define pthread_mutex_lock
Definition: lock.h:623
const char * func
Definition: main/utils.c:824
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
pthread_mutex_t lock
Definition: main/utils.c:846
const char * file
Definition: main/utils.c:823
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
Keep track of which locks a thread holds.
Definition: main/utils.c:816
#define pthread_mutex_unlock
Definition: lock.h:624

◆ ast_format_duration_hh_mm_ss()

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 2049 of file main/utils.c.

Referenced by cli_channel_print_body(), cli_channelstats_print_body(), handle_bridge_show_all(), handle_bridge_show_specific(), show_chanstats_cb(), and stasis_show_topic().

2050 {
2051  int durh, durm, durs;
2052  durh = duration / 3600;
2053  durm = (duration % 3600) / 60;
2054  durs = duration % 60;
2055  snprintf(buf, length, "%02d:%02d:%02d", durh, durm, durs);
2056 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

◆ ast_get_tid()

int ast_get_tid ( void  )

Get current thread ID.

Returns
the ID if platform is supported, else -1

Definition at line 2504 of file main/utils.c.

Referenced by __ao2_ref(), ast_hangup(), ast_register_thread(), dummy_start(), format_log_message_ap(), and internal_ao2_alloc().

2505 {
2506  int ret = -1;
2507 #if defined (__linux) && defined(SYS_gettid)
2508  ret = syscall(SYS_gettid); /* available since Linux 1.4.11 */
2509 #elif defined(__sun)
2510  ret = pthread_self();
2511 #elif defined(__APPLE__)
2512  ret = mach_thread_self();
2513  mach_port_deallocate(mach_task_self(), ret);
2514 #elif defined(__FreeBSD__) && defined(HAVE_SYS_THR_H)
2515  long lwpid;
2516  thr_self(&lwpid); /* available since sys/thr.h creation 2003 */
2517  ret = lwpid;
2518 #endif
2519  return ret;
2520 }

◆ ast_get_time_t()

int ast_get_time_t ( const char *  src,
time_t *  dst,
time_t  _default,
int *  consumed 
)

get values from config variables.

Definition at line 2198 of file main/utils.c.

References ast_strlen_zero, and NULL.

Referenced by build_peer(), cache_lookup_internal(), dundi_show_cache(), dundi_show_hints(), handle_saydatetime(), load_password(), play_message_datetime(), process_clearcache(), realtime_peer(), and sayunixtime_exec().

2199 {
2200  long t;
2201  int scanned;
2202 
2203  if (dst == NULL)
2204  return -1;
2205 
2206  *dst = _default;
2207 
2208  if (ast_strlen_zero(src))
2209  return -1;
2210 
2211  /* only integer at the moment, but one day we could accept more formats */
2212  if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
2213  *dst = t;
2214  if (consumed)
2215  *consumed = scanned;
2216  return 0;
2217  } else
2218  return -1;
2219 }
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52

◆ ast_get_timeval()

int ast_get_timeval ( const char *  src,
struct timeval *  dst,
struct timeval  _default,
int *  consumed 
)

get values from config variables.

Definition at line 2171 of file main/utils.c.

References ast_strlen_zero, and NULL.

Referenced by acf_strftime(), expiration_str2struct(), persistence_expires_str2struct(), and timeval_str2struct().

2172 {
2173  long double dtv = 0.0;
2174  int scanned;
2175 
2176  if (dst == NULL)
2177  return -1;
2178 
2179  *dst = _default;
2180 
2181  if (ast_strlen_zero(src))
2182  return -1;
2183 
2184  /* only integer at the moment, but one day we could accept more formats */
2185  if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
2186  dst->tv_sec = dtv;
2187  dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
2188  if (consumed)
2189  *consumed = scanned;
2190  return 0;
2191  } else
2192  return -1;
2193 }
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52

◆ ast_gethostbyname()

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 197 of file main/utils.c.

References ast_hostent::buf, host, ast_hostent::hp, and NULL.

Referenced by ast_parse_arg(), config_load(), config_parse_variables(), festival_exec(), iax_template_parse(), process_sdp(), and reload_config().

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

◆ ast_inet_ntoa()

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 782 of file main/utils.c.

References ast_threadstorage_get(), buf, and inet_ntoa_buf.

Referenced by _skinny_show_device(), _skinny_show_devices(), _stun_show_status(), add_sdp(), ast_dns_get_nameservers(), ast_parse_arg(), config_load(), create_client(), find_command(), find_subchannel_and_lock(), get_defaults(), get_to_address(), handle_error(), handle_mgcp_show_endpoints(), handle_open_receive_channel_ack_message(), handle_request(), handle_skinny_show_settings(), iax_server(), mgcpsock_read(), parsing(), process_request(), process_sdp(), reload_config(), resend_response(), rtp_add_candidates_to_ice(), rtp_reload(), score_address(), send_raw_client(), send_request(), send_response(), send_start_rtp(), send_trunk(), show_main_page(), skinny_session(), skinny_session_cleanup(), skinny_set_rtp_peer(), start_rtp(), stun_monitor_request(), transmit_serverres(), transmit_startmediatransmission(), unistim_show_devices(), unistim_show_info(), and unistimsock_read().

783 {
784  char *buf;
785 
786  if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
787  return "";
788 
789  return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
790 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static struct ast_threadstorage inet_ntoa_buf
Definition: main/utils.c:83

◆ ast_join_delim()

void ast_join_delim ( char *  s,
size_t  len,
const char *const  w[],
unsigned int  size,
char  delim 
)

Definition at line 2130 of file main/utils.c.

References len().

Referenced by ast_sip_auths_to_str().

2131 {
2132  int x, ofs = 0;
2133  const char *src;
2134 
2135  /* Join words into a string */
2136  if (!s)
2137  return;
2138  for (x = 0; ofs < len && x < size && w[x] ; x++) {
2139  if (x > 0)
2140  s[ofs++] = delim;
2141  for (src = w[x]; *src && ofs < len; src++)
2142  s[ofs++] = *src;
2143  }
2144  if (ofs == len)
2145  ofs--;
2146  s[ofs] = '\0';
2147 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ ast_log_show_lock()

void ast_log_show_lock ( void *  this_lock_addr)

log info for the current lock with ast_log().

This function can help you find highly temporal locks; locks that happen for a short time, but at unexpected times, usually at times that create a deadlock, Why is this thing locked right then? Who is locking it? Who am I fighting with for this lock?

To answer such questions, just call this routine before you would normally try to aquire a lock. It doesn't do anything if the lock is not acquired. If the lock is taken, it will publish a line or two to the console via ast_log().

Sometimes, the lock message is pretty uninformative. For instance, you might find that the lock is being aquired deep within the astobj2 code; this tells you little about higher level routines that call the astobj2 routines. But, using gdb, you can set a break at the ast_log below, and for that breakpoint, you can set the commands: where cont which will give a stack trace and continue. – that aught to do the job!

Definition at line 1231 of file main/utils.c.

References append_lock_information(), ast_free, AST_LIST_TRAVERSE, ast_log, ast_str_buffer(), ast_str_create, thr_lock_info::lock, thr_lock_info::lock_addr, lock_info, lock_infos_lock, thr_lock_info::locks, LOG_NOTICE, ast_mutex_info::mutex, thr_lock_info::num_locks, pthread_mutex_lock, pthread_mutex_unlock, and str.

1232 {
1233 #if !defined(LOW_MEMORY)
1234  struct thr_lock_info *lock_info;
1235  struct ast_str *str;
1236 
1237  if (!(str = ast_str_create(4096))) {
1238  ast_log(LOG_NOTICE,"Could not create str\n");
1239  return;
1240  }
1241 
1242 
1244  AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
1245  int i;
1246  pthread_mutex_lock(&lock_info->lock);
1247  for (i = 0; str && i < lock_info->num_locks; i++) {
1248  /* ONLY show info about this particular lock, if
1249  it's acquired... */
1250  if (lock_info->locks[i].lock_addr == this_lock_addr) {
1251  append_lock_information(&str, lock_info, i);
1252  ast_log(LOG_NOTICE, "%s", ast_str_buffer(str));
1253  break;
1254  }
1255  }
1256  pthread_mutex_unlock(&lock_info->lock);
1257  }
1259  ast_free(str);
1260 #endif /* ! LOW_MEMORY */
1261 }
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
Definition: main/utils.c:1174
unsigned int num_locks
Definition: main/utils.c:841
const char * str
Definition: app_jack.c:147
void * lock_addr
Definition: main/utils.c:826
#define ast_log
Definition: astobj2.c:42
static ast_mutex_t lock_infos_lock
Locked when accessing the lock_infos list.
Definition: main/utils.c:853
#define pthread_mutex_lock
Definition: lock.h:623
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
pthread_mutex_t lock
Definition: main/utils.c:846
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_free(a)
Definition: astmm.h:182
A list of each thread&#39;s lock info.
Definition: main/utils.c:857
Keep track of which locks a thread holds.
Definition: main/utils.c:816
pthread_mutex_t mutex
Definition: lock.h:136
Definition: search.h:40
#define pthread_mutex_unlock
Definition: lock.h:624
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ ast_mark_lock_acquired()

void ast_mark_lock_acquired ( void *  lock_addr)

Mark the last lock as acquired.

Definition at line 962 of file main/utils.c.

References ast_threadstorage_get(), thr_lock_info::lock, thr_lock_info::lock_addr, lock_info, thr_lock_info::locks, thr_lock_info::num_locks, thr_lock_info::pending, pthread_mutex_lock, pthread_mutex_unlock, and thread_lock_info.

963 {
964 #if !defined(LOW_MEMORY)
965  struct thr_lock_info *lock_info;
966 
967  if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
968  return;
969 
970  pthread_mutex_lock(&lock_info->lock);
971  if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
972  lock_info->locks[lock_info->num_locks - 1].pending = 0;
973  }
974  pthread_mutex_unlock(&lock_info->lock);
975 #endif /* ! LOW_MEMORY */
976 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
static struct ast_threadstorage thread_lock_info
Definition: main/utils.c:902
unsigned int num_locks
Definition: main/utils.c:841
void * lock_addr
Definition: main/utils.c:826
#define pthread_mutex_lock
Definition: lock.h:623
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
pthread_mutex_t lock
Definition: main/utils.c:846
Keep track of which locks a thread holds.
Definition: main/utils.c:816
#define pthread_mutex_unlock
Definition: lock.h:624

◆ ast_mark_lock_failed()

void ast_mark_lock_failed ( void *  lock_addr)

Mark the last lock as failed (trylock)

Definition at line 978 of file main/utils.c.

References ast_threadstorage_get(), thr_lock_info::lock, thr_lock_info::lock_addr, lock_info, thr_lock_info::locks, thr_lock_info::num_locks, thr_lock_info::pending, pthread_mutex_lock, pthread_mutex_unlock, thread_lock_info, and thr_lock_info::times_locked.

979 {
980 #if !defined(LOW_MEMORY)
981  struct thr_lock_info *lock_info;
982 
983  if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
984  return;
985 
986  pthread_mutex_lock(&lock_info->lock);
987  if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
988  lock_info->locks[lock_info->num_locks - 1].pending = -1;
989  lock_info->locks[lock_info->num_locks - 1].times_locked--;
990  }
991  pthread_mutex_unlock(&lock_info->lock);
992 #endif /* ! LOW_MEMORY */
993 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
static struct ast_threadstorage thread_lock_info
Definition: main/utils.c:902
unsigned int num_locks
Definition: main/utils.c:841
void * lock_addr
Definition: main/utils.c:826
#define pthread_mutex_lock
Definition: lock.h:623
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
pthread_mutex_t lock
Definition: main/utils.c:846
Keep track of which locks a thread holds.
Definition: main/utils.c:816
#define pthread_mutex_unlock
Definition: lock.h:624

◆ ast_md5_hash()

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 248 of file main/utils.c.

References MD5Final(), MD5Init(), and MD5Update().

Referenced by __init_manager(), ast_sip_location_create_contact(), AST_TEST_DEFINE(), auth_exec(), auth_http_callback(), build_nonce(), build_reply_digest(), check_auth(), md5(), and permanent_uri_handler().

249 {
250  struct MD5Context md5;
251  unsigned char digest[16];
252  char *ptr;
253  int x;
254 
255  MD5Init(&md5);
256  MD5Update(&md5, (const unsigned char *) input, strlen(input));
257  MD5Final(digest, &md5);
258  ptr = output;
259  for (x = 0; x < 16; x++)
260  ptr += sprintf(ptr, "%02hhx", digest[x]);
261 }
void MD5Final(unsigned char digest[16], struct MD5Context *context)
Definition: md5.c:120
static int input(yyscan_t yyscanner)
Definition: ast_expr2f.c:1584
void MD5Init(struct MD5Context *context)
Definition: md5.c:57
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
Definition: md5.c:72
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_md5.c:52
Definition: md5.h:26

◆ ast_mkdir()

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
Returns
0 on success or an error code otherwise

Creates a directory path, creating parent directories as needed.

Definition at line 2231 of file main/utils.c.

References ast_alloca, ast_strdupa, errno, len(), and tmp().

Referenced by ast_logger_rotate_channel(), ast_monitor_change_fname(), ast_monitor_start(), conf_rec_name(), conf_run(), create_destination_directory(), create_dirpath(), create_temp_file(), dictate_exec(), filename_parse(), init_logger(), load_module(), reload_logger(), remove_from_queue(), setup_privacy_args(), sms_nextoutgoing(), sms_writefile(), test_vm_api_create_voicemail_folder(), testclient_exec(), testserver_exec(), and write_history().

2232 {
2233  char *ptr;
2234  int len = strlen(path), count = 0, x, piececount = 0;
2235  char *tmp = ast_strdupa(path);
2236  char **pieces;
2237  char *fullpath = ast_alloca(len + 1);
2238  int res = 0;
2239 
2240  for (ptr = tmp; *ptr; ptr++) {
2241  if (*ptr == '/')
2242  count++;
2243  }
2244 
2245  /* Count the components to the directory path */
2246  pieces = ast_alloca(count * sizeof(*pieces));
2247  for (ptr = tmp; *ptr; ptr++) {
2248  if (*ptr == '/') {
2249  *ptr = '\0';
2250  pieces[piececount++] = ptr + 1;
2251  }
2252  }
2253 
2254  *fullpath = '\0';
2255  for (x = 0; x < piececount; x++) {
2256  /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
2257  strcat(fullpath, "/");
2258  strcat(fullpath, pieces[x]);
2259  res = mkdir(fullpath, mode);
2260  if (res && errno != EEXIST)
2261  return errno;
2262  }
2263  return 0;
2264 }
static int tmp()
Definition: bt_open.c:389
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno

◆ ast_parse_digest()

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 2390 of file main/utils.c.

References ast_free, ast_log, ast_skip_blanks(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_string_field_ptr_set, ast_string_field_set, ast_strlen_zero, ast_unescape_c(), c, ast_http_digest::cnonce, ast_http_digest::domain, LOG_WARNING, ast_http_digest::nc, ast_http_digest::nonce, NULL, ast_http_digest::opaque, ast_http_digest::qop, ast_http_digest::realm, ast_http_digest::response, str, strsep(), ast_http_digest::uri, and ast_http_digest::username.

Referenced by auth_http_callback().

2390  {
2391  char *c;
2392  struct ast_str *str = ast_str_create(16);
2393 
2394  /* table of recognised keywords, and places where they should be copied */
2395  const struct x {
2396  const char *key;
2397  const ast_string_field *field;
2398  } *i, keys[] = {
2399  { "username=", &d->username },
2400  { "realm=", &d->realm },
2401  { "nonce=", &d->nonce },
2402  { "uri=", &d->uri },
2403  { "domain=", &d->domain },
2404  { "response=", &d->response },
2405  { "cnonce=", &d->cnonce },
2406  { "opaque=", &d->opaque },
2407  /* Special cases that cannot be directly copied */
2408  { "algorithm=", NULL },
2409  { "qop=", NULL },
2410  { "nc=", NULL },
2411  { NULL, 0 },
2412  };
2413 
2414  if (ast_strlen_zero(digest) || !d || !str) {
2415  ast_free(str);
2416  return -1;
2417  }
2418 
2419  ast_str_set(&str, 0, "%s", digest);
2420 
2421  c = ast_skip_blanks(ast_str_buffer(str));
2422 
2423  if (strncasecmp(c, "Digest ", strlen("Digest "))) {
2424  ast_log(LOG_WARNING, "Missing Digest.\n");
2425  ast_free(str);
2426  return -1;
2427  }
2428  c += strlen("Digest ");
2429 
2430  /* lookup for keys/value pair */
2431  while (c && *c && *(c = ast_skip_blanks(c))) {
2432  /* find key */
2433  for (i = keys; i->key != NULL; i++) {
2434  char *src, *separator;
2435  int unescape = 0;
2436  if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
2437  continue;
2438  }
2439 
2440  /* Found. Skip keyword, take text in quotes or up to the separator. */
2441  c += strlen(i->key);
2442  if (*c == '"') {
2443  src = ++c;
2444  separator = "\"";
2445  unescape = 1;
2446  } else {
2447  src = c;
2448  separator = ",";
2449  }
2450  strsep(&c, separator); /* clear separator and move ptr */
2451  if (unescape) {
2452  ast_unescape_c(src);
2453  }
2454  if (i->field) {
2455  ast_string_field_ptr_set(d, i->field, src);
2456  } else {
2457  /* Special cases that require additional procesing */
2458  if (!strcasecmp(i->key, "algorithm=")) {
2459  if (strcasecmp(src, "MD5")) {
2460  ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src);
2461  ast_free(str);
2462  return -1;
2463  }
2464  } else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) {
2465  d->qop = 1;
2466  } else if (!strcasecmp(i->key, "nc=")) {
2467  unsigned long u;
2468  if (sscanf(src, "%30lx", &u) != 1) {
2469  ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src);
2470  ast_free(str);
2471  return -1;
2472  }
2473  ast_string_field_set(d, nc, src);
2474  }
2475  }
2476  break;
2477  }
2478  if (i->key == NULL) { /* not found, try ',' */
2479  strsep(&c, ",");
2480  }
2481  }
2482  ast_free(str);
2483 
2484  /* Digest checkout */
2485  if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
2486  /* "realm" and "nonce" MUST be always exist */
2487  return -1;
2488  }
2489 
2490  if (!request) {
2491  /* Additional check for Digest response */
2493  return -1;
2494  }
2495 
2496  if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
2497  return -1;
2498  }
2499  }
2500 
2501  return 0;
2502 }
const ast_string_field cnonce
Definition: utils.h:672
#define ast_string_field_ptr_set(x, ptr, data)
Set a field to a simple string value.
Definition: stringfields.h:470
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
const ast_string_field opaque
Definition: utils.h:672
const ast_string_field domain
Definition: utils.h:672
const char * ast_string_field
Definition: stringfields.h:190
static struct test_val c
const ast_string_field username
Definition: utils.h:672
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
const ast_string_field uri
Definition: utils.h:672
#define ast_log
Definition: astobj2.c:42
const ast_string_field response
Definition: utils.h:672
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
const ast_string_field nc
Definition: utils.h:672
#define ast_free(a)
Definition: astmm.h:182
char * ast_unescape_c(char *src)
Convert some C escape sequences.
Definition: main/utils.c:1735
const ast_string_field realm
Definition: utils.h:672
static int request(void *obj)
Definition: chan_pjsip.c:2559
const ast_string_field nonce
Definition: utils.h:672
char * strsep(char **str, const char *delims)
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ ast_process_quotes_and_slashes()

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 2104 of file main/utils.c.

2105 {
2106  char *dataPut = start;
2107  int inEscape = 0;
2108  int inQuotes = 0;
2109 
2110  for (; *start; start++) {
2111  if (inEscape) {
2112  *dataPut++ = *start; /* Always goes verbatim */
2113  inEscape = 0;
2114  } else {
2115  if (*start == '\\') {
2116  inEscape = 1; /* Do not copy \ into the data */
2117  } else if (*start == '\'') {
2118  inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
2119  } else {
2120  /* Replace , with |, unless in quotes */
2121  *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2122  }
2123  }
2124  }
2125  if (start != dataPut)
2126  *dataPut = 0;
2127  return dataPut;
2128 }

◆ ast_pthread_create_detached_stack()

int ast_pthread_create_detached_stack ( pthread_t *  thread,
pthread_attr_t *  attr,
void *(*)(void *)  start_routine,
void *  data,
size_t  stacksize,
const char *  file,
const char *  caller,
int  line,
const char *  start_fn 
)

Definition at line 1494 of file main/utils.c.

References ast_alloca, ast_log, ast_pthread_create_stack(), errno, LOG_WARNING, and thr_arg::start_routine.

1497 {
1498  unsigned char attr_destroy = 0;
1499  int res;
1500 
1501  if (!attr) {
1502  attr = ast_alloca(sizeof(*attr));
1503  pthread_attr_init(attr);
1504  attr_destroy = 1;
1505  }
1506 
1507  if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
1508  ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
1509 
1510  res = ast_pthread_create_stack(thread, attr, start_routine, data,
1511  stacksize, file, caller, line, start_fn);
1512 
1513  if (attr_destroy)
1514  pthread_attr_destroy(attr);
1515 
1516  return res;
1517 }
pthread_t thread
Definition: app_meetme.c:1089
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize, const char *file, const char *caller, int line, const char *start_fn)
Definition: main/utils.c:1446
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
int errno

◆ ast_pthread_create_stack()

int ast_pthread_create_stack ( pthread_t *  thread,
pthread_attr_t *  attr,
void *(*)(void *)  start_routine,
void *  data,
size_t  stacksize,
const char *  file,
const char *  caller,
int  line,
const char *  start_fn 
)

Definition at line 1446 of file main/utils.c.

References a, ast_alloca, ast_asprintf, ast_log, ast_malloc, AST_STACKSIZE, thr_arg::data, dummy_start(), errno, LOG_WARNING, thr_arg::name, NULL, pthread_create, and thr_arg::start_routine.

Referenced by ast_pthread_create_detached_stack().

1449 {
1450 #if !defined(LOW_MEMORY)
1451  struct thr_arg *a;
1452 #endif
1453 
1454  if (!attr) {
1455  attr = ast_alloca(sizeof(*attr));
1456  pthread_attr_init(attr);
1457  }
1458 
1459 #if defined(__linux__) || defined(__FreeBSD__)
1460  /* On Linux and FreeBSD , pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
1461  which is kind of useless. Change this here to
1462  PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
1463  priority will propagate down to new threads by default.
1464  This does mean that callers cannot set a different priority using
1465  PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
1466  the priority afterwards with pthread_setschedparam(). */
1467  if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
1468  ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
1469 #endif
1470 
1471  if (!stacksize)
1472  stacksize = AST_STACKSIZE;
1473 
1474  if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
1475  ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
1476 
1477 #if !defined(LOW_MEMORY)
1478  if ((a = ast_malloc(sizeof(*a)))) {
1480  a->data = data;
1482  if (ast_asprintf(&a->name, "%-20s started at [%5d] %s %s()",
1483  start_fn, line, file, caller) < 0) {
1484  a->name = NULL;
1485  }
1486  data = a;
1487  }
1488 #endif /* !LOW_MEMORY */
1489 
1490  return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
1491 }
pthread_t thread
Definition: app_meetme.c:1089
#define AST_STACKSIZE
Definition: utils.h:540
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
#define ast_log
Definition: astobj2.c:42
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static void * dummy_start(void *data)
Definition: main/utils.c:1394
int errno
#define pthread_create
Definition: lock.h:640
void *(* start_routine)(void *)
Definition: main/utils.c:1382
void * data
Definition: main/utils.c:1383
char * name
Definition: main/utils.c:1384
static struct test_val a

◆ ast_random()

long int ast_random ( void  )

Definition at line 2064 of file main/utils.c.

References ast_mutex_lock, ast_mutex_unlock, and randomlock.

Referenced by __sip_alloc(), acf_rand_exec(), action_challenge(), add_sdp(), agi_handle_command(), app_exec(), ast_generate_random_string(), ast_lock_path_lockfile(), ast_moh_files_next(), ast_rtp_change_source(), ast_rtp_new(), AST_TEST_DEFINE(), ast_udptl_new_with_bindaddr(), astobj2_test_1_helper(), auth_http_callback(), authenticate_request(), build_gateway(), build_iv(), build_localtag_registry(), build_nonce(), build_rand_pad(), build_reply_digest(), calc_metric(), calc_rxstamp(), caldav_write_event(), closefrom(), create_channel_name(), create_local_sdp(), dns_srv_sort(), drop_packets_data_update(), fill_with_garbage(), generate_parked_user(), generate_random_string(), generic_http_callback(), get_trans_id(), get_unused_callno(), handle_cli_sched_bench(), handle_incoming(), handle_response_invite(), iax2_key_rotate(), jingle_add_ice_udp_candidates_to_transport(), jingle_alloc(), jingle_new(), load_module(), make_email_file(), make_our_tag(), mbl_new(), moh_files_alloc(), multicast_rtp_new(), ogg_vorbis_rewrite(), osp_create_uuid(), page_exec(), process_weights(), reg_source_db(), registry_authrequest(), reqprep(), reschedule_reinvite(), rtp_allocate_transport(), say_periodic_announcement(), sendmail(), sip_outbound_registration_perform(), socket_read(), sorcery_memory_cache_thrash_retrieve(), sorcery_memory_cache_thrash_update(), start_rtp(), stun_req_id(), test_ao2_find_w_no_flags(), test_ao2_find_w_OBJ_KEY(), test_ao2_find_w_OBJ_PARTIAL_KEY(), test_ao2_find_w_OBJ_POINTER(), test_files_get_one(), transmit_invite(), transmit_register(), transmit_response_using_temp(), try_calling(), try_firmware(), websocket_client_create_key(), and websocket_mask_payload().

2065 {
2066  long int res;
2067 
2068  if (dev_urandom_fd >= 0) {
2069  int read_res = read(dev_urandom_fd, &res, sizeof(res));
2070  if (read_res > 0) {
2071  long int rm = RAND_MAX;
2072  res = res < 0 ? ~res : res;
2073  rm++;
2074  return res % rm;
2075  }
2076  }
2077 
2078  /* XXX - Thread safety really depends on the libc, not the OS.
2079  *
2080  * But... popular Linux libc's (uClibc, glibc, eglibc), all have a
2081  * somewhat thread safe random(3) (results are random, but not
2082  * reproducible). The libc's for other systems (BSD, et al.), not so
2083  * much.
2084  */
2085 #ifdef linux
2086  res = random();
2087 #else
2089  res = random();
2091 #endif
2092  return res;
2093 }
static int dev_urandom_fd
Definition: main/utils.c:792
#define ast_mutex_lock(a)
Definition: lock.h:187
static ast_mutex_t randomlock
Definition: main/utils.c:2061
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_regex_string_to_regex_pattern()

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

Returns
0 on success, non-zero on failure.
1 if we only stripped a leading /
2 if we only stripped a trailing /
3 if 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 1931 of file main/utils.c.

References ast_str_set(), and ast_str_truncate().

Referenced by action_hangup(), mwi_mailbox_delete(), and mwi_mailbox_get().

1932 {
1933  int regex_len = strlen(regex_string);
1934  int ret = 3;
1935 
1936  /* Chop off the leading / if there is one */
1937  if ((regex_len >= 1) && (regex_string[0] == '/')) {
1938  ast_str_set(regex_pattern, 0, "%s", regex_string + 1);
1939  ret -= 2;
1940  }
1941 
1942  /* Chop off the ending / if there is one */
1943  if ((regex_len > 1) && (regex_string[regex_len - 1] == '/')) {
1944  ast_str_truncate(*regex_pattern, -1);
1945  ret -= 1;
1946  }
1947 
1948  return ret;
1949 }
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:738
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065

◆ ast_remaining_ms()

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 2033 of file main/utils.c.

References ast_tvdiff_ms(), and ast_tvnow().

Referenced by __analog_ss_thread(), __ast_answer(), __ast_request_and_dial(), analog_ss_thread(), ast_iostream_write(), ast_recvtext(), ast_stun_request(), ast_waitfordigit_full(), disable_t38(), find_cache(), generic_fax_exec(), iostream_read(), parking_set_duration(), read_mf_digits(), read_sf_digits(), receivefax_t38_init(), record_exec(), safe_sleep_conditional(), sendfax_t38_init(), wait_exec(), wait_for_answer(), wait_for_cache_update(), and waitforring_exec().

2034 {
2035  int ms;
2036 
2037  if (max_ms < 0) {
2038  ms = max_ms;
2039  } else {
2040  ms = max_ms - ast_tvdiff_ms(ast_tvnow(), start);
2041  if (ms < 0) {
2042  ms = 0;
2043  }
2044  }
2045 
2046  return ms;
2047 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98

◆ ast_remove_lock_info()

void ast_remove_lock_info ( void *  lock_addr,
struct ast_bt bt 
)

remove lock info for the current thread

this gets called by ast_mutex_unlock so that information on the lock can be removed from the current thread's lock info struct.

Definition at line 1088 of file main/utils.c.

References ast_threadstorage_get(), thr_lock_info::backtrace, thr_lock_info::lock, thr_lock_info::lock_addr, lock_info, thr_lock_info::locks, thr_lock_info::num_locks, pthread_mutex_lock, pthread_mutex_unlock, thread_lock_info, and thr_lock_info::times_locked.

1089 {
1090 #if !defined(LOW_MEMORY)
1091  struct thr_lock_info *lock_info;
1092  int i = 0;
1093 
1094  if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
1095  return;
1096 
1097  pthread_mutex_lock(&lock_info->lock);
1098 
1099  for (i = lock_info->num_locks - 1; i >= 0; i--) {
1100  if (lock_info->locks[i].lock_addr == lock_addr)
1101  break;
1102  }
1103 
1104  if (i == -1) {
1105  /* Lock not found :( */
1106  pthread_mutex_unlock(&lock_info->lock);
1107  return;
1108  }
1109 
1110  if (lock_info->locks[i].times_locked > 1) {
1111  lock_info->locks[i].times_locked--;
1112 #ifdef HAVE_BKTR
1113  lock_info->locks[i].backtrace = bt;
1114 #endif
1115  pthread_mutex_unlock(&lock_info->lock);
1116  return;
1117  }
1118 
1119  if (i < lock_info->num_locks - 1) {
1120  /* Not the last one ... *should* be rare! */
1121  memmove(&lock_info->locks[i], &lock_info->locks[i + 1],
1122  (lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
1123  }
1124 
1125  lock_info->num_locks--;
1126 
1127  pthread_mutex_unlock(&lock_info->lock);
1128 #endif /* ! LOW_MEMORY */
1129 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
static struct ast_threadstorage thread_lock_info
Definition: main/utils.c:902
unsigned int num_locks
Definition: main/utils.c:841
void * lock_addr
Definition: main/utils.c:826
#define pthread_mutex_lock
Definition: lock.h:623
struct ast_bt * backtrace
Definition: main/utils.c:835
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
pthread_mutex_t lock
Definition: main/utils.c:846
Keep track of which locks a thread holds.
Definition: main/utils.c:816
#define pthread_mutex_unlock
Definition: lock.h:624

◆ ast_replace_subargument_delimiter()

void ast_replace_subargument_delimiter ( char *  s)

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

Parameters
sString within which to replace characters

Definition at line 2095 of file main/utils.c.

Referenced by app_exec(), ast_bridge_set_after_go_on(), dial_exec_full(), originate_exec(), page_exec(), and queue_exec().

2096 {
2097  for (; *s; s++) {
2098  if (*s == '^') {
2099  *s = ',';
2100  }
2101  }
2102 }

◆ ast_restore_lock_info()

void ast_restore_lock_info ( void *  lock_addr)

Definition at line 1059 of file main/utils.c.

References ast_threadstorage_get(), thr_lock_info::lock, thr_lock_info::lock_addr, lock_info, thr_lock_info::locks, thr_lock_info::num_locks, pthread_mutex_lock, pthread_mutex_unlock, thr_lock_info::suspended, and thread_lock_info.

1060 {
1061 #if !defined(LOW_MEMORY)
1062  struct thr_lock_info *lock_info;
1063  int i = 0;
1064 
1065  if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
1066  return;
1067 
1068  pthread_mutex_lock(&lock_info->lock);
1069 
1070  for (i = lock_info->num_locks - 1; i >= 0; i--) {
1071  if (lock_info->locks[i].lock_addr == lock_addr)
1072  break;
1073  }
1074 
1075  if (i == -1) {
1076  /* Lock not found :( */
1077  pthread_mutex_unlock(&lock_info->lock);
1078  return;
1079  }
1080 
1081  lock_info->locks[i].suspended = 0;
1082 
1083  pthread_mutex_unlock(&lock_info->lock);
1084 #endif /* ! LOW_MEMORY */
1085 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
static struct ast_threadstorage thread_lock_info
Definition: main/utils.c:902
unsigned int num_locks
Definition: main/utils.c:841
void * lock_addr
Definition: main/utils.c:826
#define pthread_mutex_lock
Definition: lock.h:623
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
pthread_mutex_t lock
Definition: main/utils.c:846
Keep track of which locks a thread holds.
Definition: main/utils.c:816
#define pthread_mutex_unlock
Definition: lock.h:624

◆ ast_safe_mkdir()

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
pathThe directory path to create
modeThe permissions with which to try to create the directory
Returns
0 on success or an error code otherwise

Definition at line 2336 of file main/utils.c.

References ast_free, ast_std_free(), ast_strdup, errno, NULL, RAII_VAR, and safe_mkdir().

Referenced by AST_TEST_DEFINE(), and stasis_app_control_record().

2337 {
2338  RAII_VAR(char *, absolute_base_path, NULL, ast_std_free);
2339  RAII_VAR(char *, p, NULL, ast_free);
2340 
2341  if (base_path == NULL || path == NULL) {
2342  errno = EFAULT;
2343  return errno;
2344  }
2345 
2346  p = ast_strdup(path);
2347  if (p == NULL) {
2348  errno = ENOMEM;
2349  return errno;
2350  }
2351 
2352  absolute_base_path = realpath(base_path, NULL);
2353  if (absolute_base_path == NULL) {
2354  return errno;
2355  }
2356 
2357  return safe_mkdir(absolute_base_path, p, mode);
2358 }
void ast_std_free(void *ptr)
Definition: astmm.c:1766
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#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:911
int errno
#define ast_free(a)
Definition: astmm.h:182
static int safe_mkdir(const char *base_path, char *path, int mode)
Definition: main/utils.c:2266

◆ ast_set_default_eid()

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 2749 of file main/utils.c.

References ast_debug, ast_eid_to_str(), ast_free, ast_log, ast_malloc, buf, if(), LOG_WARNING, and NULL.

Referenced by ast_eid_to_str(), and load_asterisk_conf().

2750 {
2751  int s;
2752  int i;
2753  struct ifreq *ifr;
2754  struct ifreq *ifrp;
2755  struct ifconf ifc;
2756  char *buf = NULL;
2757  char eid_str[20];
2758  int bufsz, num_interfaces;
2759  unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
2760  unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2761 
2762  s = socket(AF_INET, SOCK_STREAM, 0);
2763  if (s < 0) {
2764  ast_log(LOG_WARNING, "Unable to open socket for seeding global EID. "
2765  "You will have to set it manually.\n");
2766  return;
2767  }
2768 
2769  ifc.ifc_len = 0;
2770  ifc.ifc_buf = NULL;
2771  if (ioctl(s, SIOCGIFCONF, &ifc) || ifc.ifc_len <= 0) {
2772  ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
2773  "You will have to set it manually.\n");
2774  close(s);
2775  return;
2776  }
2777  bufsz = ifc.ifc_len;
2778 
2779  if (!(buf = ast_malloc(bufsz))) {
2780  ast_log(LOG_WARNING, "Unable to allocate memory for seeding global EID. "
2781  "You will have to set it manually.\n");
2782  close(s);
2783  return;
2784  }
2785 
2786  ifc.ifc_buf = buf;
2787  if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
2788  ast_log(LOG_WARNING, "Unable to retrieve ethernet interfaces for seeding global EID. "
2789  "You will have to set it manually.\n");
2790  ast_free(buf);
2791  close(s);
2792  return;
2793  }
2794 
2795  ifrp = ifc.ifc_req;
2796  num_interfaces = ifc.ifc_len / sizeof(*ifr);
2797 
2798  for (i = 0; i < num_interfaces; i++) {
2799  ifr = &ifrp[i];
2800  if (!ioctl(s, SIOCGIFHWADDR, ifr)) {
2801  unsigned char *hwaddr = (unsigned char *) ifr->ifr_hwaddr.sa_data;
2802 
2803  if (!(memcmp(hwaddr, &empty_mac, 6) && memcmp(hwaddr, &full_mac, 6))) {
2804  continue;
2805  }
2806 
2807  memcpy(eid, hwaddr, sizeof(*eid));
2808  ast_debug(1, "Seeding global EID '%s' from '%s' using 'siocgifhwaddr'\n",
2809  ast_eid_to_str(eid_str, sizeof(eid_str), eid), ifr->ifr_name);
2810  ast_free(buf);
2811  close(s);
2812  return;
2813  }
2814  }
2815 
2816  ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
2817  "You will have to set it manually.\n");
2818  ast_free(buf);
2819  close(s);
2820 
2821  return;
2822 }
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: main/utils.c:2587
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define ast_free(a)
Definition: astmm.h:182

◆ ast_sha1_hash()

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 264 of file main/utils.c.

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

Referenced by add_public_key_to_astdb(), ast_tcptls_server_start(), AST_TEST_DEFINE(), get_path_to_public_key(), handle_call_token(), media_cache_item_sync_to_astdb(), public_key_is_expired(), remove_public_key_from_astdb(), set_public_key_expiration(), sha1(), test_stir_shaken_add_fake_astdb_entry(), xmpp_client_authenticate_digest(), and xmpp_component_authenticate().

265 {
266  struct SHA1Context sha;
267  char *ptr;
268  int x;
269  uint8_t Message_Digest[20];
270 
271  SHA1Reset(&sha);
272 
273  SHA1Input(&sha, (const unsigned char *) input, strlen(input));
274 
275  SHA1Result(&sha, Message_Digest);
276  ptr = output;
277  for (x = 0; x < 20; x++)
278  ptr += sprintf(ptr, "%02hhx", Message_Digest[x]);
279 }
static int input(yyscan_t yyscanner)
Definition: ast_expr2f.c:1584
int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1HashSize])
Definition: sha1.c:226
int SHA1Reset(SHA1Context *)
SHA1Reset.
Definition: sha1.c:101
int SHA1Input(SHA1Context *, const uint8_t *bytes, unsigned int bytecount)

◆ ast_sha1_hash_uint()

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 282 of file main/utils.c.

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

Referenced by websocket_combine_key().

283 {
284  struct SHA1Context sha;
285 
286  SHA1Reset(&sha);
287 
288  SHA1Input(&sha, (const unsigned char *) input, strlen(input));
289 
290  SHA1Result(&sha, digest);
291 }
static int input(yyscan_t yyscanner)
Definition: ast_expr2f.c:1584
int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1HashSize])
Definition: sha1.c:226
int SHA1Reset(SHA1Context *)
SHA1Reset.
Definition: sha1.c:101
int SHA1Input(SHA1Context *, const uint8_t *bytes, unsigned int bytecount)

◆ ast_store_lock_info()

void ast_store_lock_info ( enum ast_lock_type  type,
const char *  filename,
int  line_num,
const char *  func,
const char *  lock_name,
void *  lock_addr,
struct ast_bt bt 
)

Store lock info for the current thread.

This function gets called in ast_mutex_lock() and ast_mutex_trylock() so that information about this lock can be stored in this thread's lock info struct. The lock is marked as pending as the thread is waiting on the lock. ast_mark_lock_acquired() will mark it as held by this thread.

Definition at line 905 of file main/utils.c.

References AST_MAX_LOCKS, ast_threadstorage_get(), thr_lock_info::backtrace, thr_lock_info::file, thr_lock_info::func, thr_lock_info::line_num, thr_lock_info::lock, thr_lock_info::lock_addr, lock_info, thr_lock_info::lock_name, thr_lock_info::locks, thr_lock_info::num_locks, thr_lock_info::pending, pthread_mutex_lock, pthread_mutex_unlock, thread_lock_info, thr_lock_info::times_locked, and thr_lock_info::type.

907 {
908 #if !defined(LOW_MEMORY)
909  struct thr_lock_info *lock_info;
910  int i;
911 
912  if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
913  return;
914 
915  pthread_mutex_lock(&lock_info->lock);
916 
917  for (i = 0; i < lock_info->num_locks; i++) {
918  if (lock_info->locks[i].lock_addr == lock_addr) {
919  lock_info->locks[i].times_locked++;
920 #ifdef HAVE_BKTR
921  lock_info->locks[i].backtrace = bt;
922 #endif
923  pthread_mutex_unlock(&lock_info->lock);
924  return;
925  }
926  }
927 
928  if (lock_info->num_locks == AST_MAX_LOCKS) {
929  /* Can't use ast_log here, because it will cause infinite recursion */
930  fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
931  " Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
932  pthread_mutex_unlock(&lock_info->lock);
933  return;
934  }
935 
936  if (i && lock_info->locks[i - 1].pending == -1) {
937  /* The last lock on the list was one that this thread tried to lock but
938  * failed at doing so. It has now moved on to something else, so remove
939  * the old lock from the list. */
940  i--;
941  lock_info->num_locks--;
942  memset(&lock_info->locks[i], 0, sizeof(lock_info->locks[0]));
943  }
944 
945  lock_info->locks[i].file = filename;
946  lock_info->locks[i].line_num = line_num;
947  lock_info->locks[i].func = func;
948  lock_info->locks[i].lock_name = lock_name;
949  lock_info->locks[i].lock_addr = lock_addr;
950  lock_info->locks[i].times_locked = 1;
951  lock_info->locks[i].type = type;
952  lock_info->locks[i].pending = 1;
953 #ifdef HAVE_BKTR
954  lock_info->locks[i].backtrace = bt;
955 #endif
956  lock_info->num_locks++;
957 
958  pthread_mutex_unlock(&lock_info->lock);
959 #endif /* ! LOW_MEMORY */
960 }
static const char type[]
Definition: chan_ooh323.c:109
#define AST_MAX_LOCKS
A reasonable maximum number of locks a thread would be holding ...
Definition: main/utils.c:802
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
const char * lock_name
Definition: main/utils.c:825
static struct ast_threadstorage thread_lock_info
Definition: main/utils.c:902
unsigned int num_locks
Definition: main/utils.c:841
void * lock_addr
Definition: main/utils.c:826
#define pthread_mutex_lock
Definition: lock.h:623
struct ast_bt * backtrace
Definition: main/utils.c:835
enum ast_lock_type type
Definition: main/utils.c:829
const char * func
Definition: main/utils.c:824
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
pthread_mutex_t lock
Definition: main/utils.c:846
const char * file
Definition: main/utils.c:823
Keep track of which locks a thread holds.
Definition: main/utils.c:816
#define pthread_mutex_unlock
Definition: lock.h:624

◆ ast_str_to_eid()

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

Returns
0 success, non-zero failure
Since
1.6.1

Definition at line 2825 of file main/utils.c.

References ast_eid::eid.

Referenced by asterisk_publication_devicestate_state_change(), asterisk_publication_mwi_state_change(), build_peer(), dundi_do_query(), load_asterisk_conf(), set_config(), and xmpp_pubsub_handle_event().

2826 {
2827  unsigned int eid_int[6];
2828  int x;
2829 
2830  if (sscanf(s, "%2x:%2x:%2x:%2x:%2x:%2x", &eid_int[0], &eid_int[1], &eid_int[2],
2831  &eid_int[3], &eid_int[4], &eid_int[5]) != 6) {
2832  return -1;
2833  }
2834 
2835  for (x = 0; x < 6; x++) {
2836  eid->eid[x] = eid_int[x];
2837  }
2838 
2839  return 0;
2840 }
unsigned char eid[6]
Definition: utils.h:787

◆ ast_strip_quoted()

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:

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

Definition at line 1639 of file main/utils.c.

References ast_strip().

Referenced by applicationmap_handler(), ast_callerid_parse(), ast_sip_validate_uri_length(), ast_strsep(), dialog_info_generate_body_content(), get_rdnis(), hfp_parse_clip(), iftime(), load_values_config(), parse_allowed_methods(), parse_cookies(), parse_dial_string(), pidf_allocate_body(), set_redirecting_reason(), sip_parse_register_line(), and xpidf_allocate_body().

1640 {
1641  char *e;
1642  char *q;
1643 
1644  s = ast_strip(s);
1645  if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
1646  e = s + strlen(s) - 1;
1647  if (*e == *(end_quotes + (q - beg_quotes))) {
1648  s++;
1649  *e = '\0';
1650  }
1651  }
1652 
1653  return s;
1654 }
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219

◆ ast_strsep()

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

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:

char *mystr = ast_strdupa("abc=def,ghi='zzz=yyy,456',jkl");
char *token, *token2, *token3;
while((token = ast_strsep(&mystr, ',', AST_SEP_STRIP))) {
// 1st token will be aaa=def
// 2nd token will be ghi='zzz=yyy,456'
while((token2 = ast_strsep(&token, '=', AST_SEP_STRIP))) {
// 1st token2 will be ghi
// 2nd token2 will be zzz=yyy,456
while((token3 = ast_strsep(&token2, ',', AST_SEP_STRIP))) {
// 1st token3 will be zzz=yyy
// 2nd token3 will be 456
// and so on
}
}
// 3rd token will be jkl
}

Definition at line 1656 of file main/utils.c.

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

Referenced by AST_TEST_DEFINE(), does_category_match(), handle_updates(), originate_exec(), test_xml_entry(), and wizard_apply_handler().

1657 {
1658  char *st = *iss;
1659  char *is;
1660  int inquote = 0;
1661  int found = 0;
1662  char stack[8];
1663 
1664  if (ast_strlen_zero(st)) {
1665  return NULL;
1666  }
1667 
1668  memset(stack, 0, sizeof(stack));
1669 
1670  for(is = st; *is; is++) {
1671  if (*is == '\\') {
1672  if (*++is != '\0') {
1673  is++;
1674  } else {
1675  break;
1676  }
1677  }
1678 
1679  if (*is == '\'' || *is == '"') {
1680  if (*is == stack[inquote]) {
1681  stack[inquote--] = '\0';
1682  } else {
1683  if (++inquote >= sizeof(stack)) {
1684  return NULL;
1685  }
1686  stack[inquote] = *is;
1687  }
1688  }
1689 
1690  if (*is == sep && !inquote) {
1691  *is = '\0';
1692  found = 1;
1693  *iss = is + 1;
1694  break;
1695  }
1696  }
1697  if (!found) {
1698  *iss = NULL;
1699  }
1700 
1701  if (flags & AST_STRSEP_STRIP) {
1702  st = ast_strip_quoted(st, "'\"", "'\"");
1703  }
1704 
1705  if (flags & AST_STRSEP_TRIM) {
1706  st = ast_strip(st);
1707  }
1708 
1709  if (flags & AST_STRSEP_UNESCAPE) {
1710  ast_unescape_quoted(st);
1711  }
1712 
1713  return st;
1714 }
void ast_unescape_quoted(char *quote_str)
Unescape quotes in a string.
Definition: main/utils.c:696
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: main/utils.c:1639
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219

◆ ast_suspend_lock_info()

void ast_suspend_lock_info ( void *  lock_addr)

Definition at line 1030 of file main/utils.c.

References ast_threadstorage_get(), thr_lock_info::lock, thr_lock_info::lock_addr, lock_info, thr_lock_info::locks, thr_lock_info::num_locks, pthread_mutex_lock, pthread_mutex_unlock, thr_lock_info::suspended, and thread_lock_info.

1031 {
1032 #if !defined(LOW_MEMORY)
1033  struct thr_lock_info *lock_info;
1034  int i = 0;
1035 
1036  if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info)))) {
1037  return;
1038  }
1039 
1040  pthread_mutex_lock(&lock_info->lock);
1041 
1042  for (i = lock_info->num_locks - 1; i >= 0; i--) {
1043  if (lock_info->locks[i].lock_addr == lock_addr)
1044  break;
1045  }
1046 
1047  if (i == -1) {
1048  /* Lock not found :( */
1049  pthread_mutex_unlock(&lock_info->lock);
1050  return;
1051  }
1052 
1053  lock_info->locks[i].suspended = 1;
1054 
1055  pthread_mutex_unlock(&lock_info->lock);
1056 #endif /* ! LOW_MEMORY */
1057 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
static struct ast_threadstorage thread_lock_info
Definition: main/utils.c:902
unsigned int num_locks
Definition: main/utils.c:841
void * lock_addr
Definition: main/utils.c:826
#define pthread_mutex_lock
Definition: lock.h:623
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
pthread_mutex_t lock
Definition: main/utils.c:846
Keep track of which locks a thread holds.
Definition: main/utils.c:816
#define pthread_mutex_unlock
Definition: lock.h:624

◆ ast_thread_is_user_interface()

int ast_thread_is_user_interface ( void  )

Indicates whether the current thread is a user interface.

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

Definition at line 2996 of file main/utils.c.

References ast_log, ast_threadstorage_get(), LOG_ERROR, NULL, and thread_user_interface_tl.

Referenced by ast_autoservice_start(), and ast_autoservice_stop().

2997 {
2998  int *thread_user_interface;
2999 
3000  thread_user_interface = ast_threadstorage_get(
3001  &thread_user_interface_tl, sizeof(*thread_user_interface));
3002  if (thread_user_interface == NULL) {
3003  ast_log(LOG_ERROR, "Error checking thread's user interface status\n");
3004  /* On error, assume that we are not a user interface thread */
3005  return 0;
3006  }
3007 
3008  return *thread_user_interface;
3009 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static struct ast_threadstorage thread_user_interface_tl
Definition: main/utils.c:2979

◆ ast_thread_user_interface_set()

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.
Returns
0 if successfuly marked current thread.
Non-zero if marking current thread failed.

Definition at line 2981 of file main/utils.c.

References ast_log, ast_threadstorage_get(), LOG_ERROR, NULL, and thread_user_interface_tl.

Referenced by handle_tcptls_connection().

2982 {
2983  int *thread_user_interface;
2984 
2985  thread_user_interface = ast_threadstorage_get(
2986  &thread_user_interface_tl, sizeof(*thread_user_interface));
2987  if (thread_user_interface == NULL) {
2988  ast_log(LOG_ERROR, "Error setting user interface status for current thread\n");
2989  return -1;
2990  }
2991 
2992  *thread_user_interface = !!is_user_interface;
2993  return 0;
2994 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static struct ast_threadstorage thread_user_interface_tl
Definition: main/utils.c:2979

◆ ast_to_camel_case_delim()

char* ast_to_camel_case_delim ( const char *  s,
const char *  delim 
)

Definition at line 2149 of file main/utils.c.

References ast_copy_string(), ast_strdup, and NULL.

2150 {
2151  char *res = ast_strdup(s);
2152  char *front, *back, *buf = res;
2153  int size;
2154 
2155  front = strtok_r(buf, delim, &back);
2156 
2157  while (front) {
2158  size = strlen(front);
2159  *front = toupper(*front);
2160  ast_copy_string(buf, front, size + 1);
2161  buf += size;
2162  front = strtok_r(NULL, delim, &back);
2163  }
2164 
2165  return res;
2166 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ ast_true()

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
0if val is a NULL pointer.
-1if "true".
0otherwise.

Definition at line 1951 of file main/utils.c.

References ast_strlen_zero.

Referenced by __ast_http_load(), __init_manager(), _parse(), acf_curlopt_write(), acf_faxopt_write(), acf_transaction_write(), action_agent_logoff(), action_originate(), action_status(), action_updateconfig(), actual_load_config(), agent_login_channel_config(), announce_user_count_all_handler(), aoc_cli_debug_enable(), apply_general_options(), apply_option(), ast_ari_bridges_add_channel_cb(), ast_ari_bridges_record_cb(), ast_ari_channels_record_cb(), ast_ari_events_event_websocket_ws_attempted_cb(), ast_ari_events_event_websocket_ws_established_cb(), ast_bridge_timelimit(), ast_jb_read_conf(), ast_rtp_dtls_cfg_parse(), AST_TEST_DEFINE(), ast_tls_read_conf(), autopause2int(), bool_handler_fn(), boolflag_handler_fn(), build_calendar(), build_device(), build_gateway(), build_peer(), build_user(), cdr_prop_write_callback(), check_debug(), client_bitfield_handler(), config_parse_variables(), custom_bitfield_handler(), customopt_handler(), dahdi_cc_callback(), dahdi_set_dnd(), destroy_all_channels(), do_reload(), encoding_format_handler(), festival_exec(), func_channel_write_real(), func_mute_write(), function_ooh323_write(), get_encrypt_methods(), global_bitfield_handler(), handle_clear_alarms(), handle_common_options(), handle_logger_set_level(), handle_queue_set_member_ringinuse(), handle_t38_options(), hook_write(), init_logger_chain(), internal_feature_write(), is_variable_true(), load_asterisk_conf(), load_config(), load_config_meetme(), load_module(), load_moh_classes(), load_odbc_config(), loader_config_init(), manager_add_queue_member(), manager_dialplan_extension_add(), manager_mute_mixmonitor(), manager_mutestream(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_member_ringinuse(), mbl_load_adapter(), mbl_load_device(), message_template_build(), misdn_answer(), moh_parse_options(), my_load_module(), new_realtime_sqlite3_db(), odbc_load_module(), osp_load(), osplookup_exec(), parse_config(), parse_empty_options(), parse_line(), parse_playtone(), pbx_builtin_saycharacters(), pbx_builtin_saycharacters_case(), pbx_builtin_saydigits(), pbx_builtin_saymoney(), pbx_builtin_saynumber(), pbx_builtin_sayphonetic(), pbx_load_config(), pbx_load_users(), pjsip_acf_moh_passthrough_write(), pjsip_set_logger_verbose(), prack_handler(), process_dahdi(), process_echocancel(), process_my_load_module(), profile_set_param(), queue_rules_set_global_params(), queue_set_global_params(), queue_set_param(), realtime_directory(), reload(), reload_config(), reload_followme(), reload_module(), reload_single_member(), rt_handle_member_record(), rtp_reload(), run_agi(), run_startup_commands(), sayunixtime_exec(), search_directory(), search_directory_sub(), set_active(), set_config(), sla_load_config(), smdi_load(), sorcery_config_open(), sorcery_memory_cache_ami_stale_object(), sorcery_memory_cache_open(), speex_write(), stackpeek_read(), start_monitor_action(), strings_to_mask(), tds_load_module(), timers_handler(), transport_tls_bool_handler(), xfer_set(), xmldoc_get_syntax_cmd(), xmldoc_get_syntax_config_object(), xmldoc_get_syntax_fun(), and xmldoc_get_syntax_manager().

1952 {
1953  if (ast_strlen_zero(s))
1954  return 0;
1955 
1956  /* Determine if this is a true value */
1957  if (!strcasecmp(s, "yes") ||
1958  !strcasecmp(s, "true") ||
1959  !strcasecmp(s, "y") ||
1960  !strcasecmp(s, "t") ||
1961  !strcasecmp(s, "1") ||
1962  !strcasecmp(s, "on"))
1963  return -1;
1964 
1965  return 0;
1966 }
#define ast_strlen_zero(foo)
Definition: strings.h:52

◆ ast_tvadd()

struct timeval ast_tvadd ( struct timeval  a,
struct timeval  b 
)

Returns the sum of two timevals a + b.

Definition at line 2005 of file main/utils.c.

References a, b, ONE_MILLION, and tvfix().

2006 {
2007  /* consistency checks to guarantee usec in 0..999999 */
2008  a = tvfix(a);
2009  b = tvfix(b);
2010  a.tv_sec += b.tv_sec;
2011  a.tv_usec += b.tv_usec;
2012  if (a.tv_usec >= ONE_MILLION) {
2013  a.tv_sec++;
2014  a.tv_usec -= ONE_MILLION;
2015  }
2016  return a;
2017 }
#define ONE_MILLION
Definition: main/utils.c:1985
static struct timeval tvfix(struct timeval a)
Definition: main/utils.c:1990
static struct test_val b
static struct test_val a

◆ ast_tvsub()

struct timeval ast_tvsub ( struct timeval  a,
struct timeval  b 
)

Returns the difference of two timevals a - b.

Definition at line 2019 of file main/utils.c.

References a, b, ONE_MILLION, and tvfix().

2020 {
2021  /* consistency checks to guarantee usec in 0..999999 */
2022  a = tvfix(a);
2023  b = tvfix(b);
2024  a.tv_sec -= b.tv_sec;
2025  a.tv_usec -= b.tv_usec;
2026  if (a.tv_usec < 0) {
2027  a.tv_sec-- ;
2028  a.tv_usec += ONE_MILLION;
2029  }
2030  return a;
2031 }
#define ONE_MILLION
Definition: main/utils.c:1985
static struct timeval tvfix(struct timeval a)
Definition: main/utils.c:1990
static struct test_val b
static struct test_val a

◆ ast_unescape_c()

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 1735 of file main/utils.c.

References c, and NULL.

Referenced by ast_parse_digest().

1736 {
1737  char c, *ret, *dst;
1738 
1739  if (src == NULL)
1740  return NULL;
1741  for (ret = dst = src; (c = *src++); *dst++ = c ) {
1742  if (c != '\\')
1743  continue; /* copy char at the end of the loop */
1744  switch ((c = *src++)) {
1745  case '\0': /* special, trailing '\' */
1746  c = '\\';
1747  break;
1748  case 'b': /* backspace */
1749  c = '\b';
1750  break;
1751  case 'f': /* form feed */
1752  c = '\f';
1753  break;
1754  case 'n':
1755  c = '\n';
1756  break;
1757  case 'r':
1758  c = '\r';
1759  break;
1760  case 't':
1761  c = '\t';
1762  break;
1763  }
1764  /* default, use the char literally */
1765  }
1766  *dst = '\0';
1767  return ret;
1768 }
static struct test_val c
#define NULL
Definition: resample.c:96

◆ ast_unescape_quoted()

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 696 of file main/utils.c.

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

697 {
698  int esc_pos;
699  int unesc_pos;
700  int quote_str_len = strlen(quote_str);
701 
702  for (esc_pos = 0, unesc_pos = 0;
703  esc_pos < quote_str_len;
704  esc_pos++, unesc_pos++) {
705  if (quote_str[esc_pos] == '\\') {
706  /* at least one more char and current is \\ */
707  esc_pos++;
708  if (esc_pos >= quote_str_len) {
709  break;
710  }
711  }
712 
713  quote_str[unesc_pos] = quote_str[esc_pos];
714  }
715  quote_str[unesc_pos] = '\0';
716 }

◆ ast_unescape_semicolon()

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 1716 of file main/utils.c.

Referenced by sip_cli_notify().

1717 {
1718  char *e;
1719  char *work = s;
1720 
1721  while ((e = strchr(work, ';'))) {
1722  if ((e > work) && (*(e-1) == '\\')) {
1723  memmove(e - 1, e, strlen(e) + 1);
1724  work = e;
1725  } else {
1726  work = e + 1;
1727  }
1728  }
1729 
1730  return s;
1731 }

◆ ast_uri_decode()

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 616 of file main/utils.c.

References ast_test_flag, AST_URI_LEGACY_SPACE, and tmp().

Referenced by acf_curl_helper(), ast_ari_invoke(), ast_http_get_post_vars(), AST_TEST_DEFINE(), config_curl(), get_destination(), get_name_and_number(), get_refer_info(), handle_request_invite(), handle_uri(), parse_moved_contact(), realtime_curl(), realtime_multi_curl(), sip_new(), sip_uri_cmp(), and uridecode().

617 {
618  char *o;
619  unsigned int tmp;
620 
621  for (o = s; *s; s++, o++) {
622  if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *s == '+') {
623  /* legacy mode, decode '+' as space */
624  *o = ' ';
625  } else if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) {
626  /* have '%', two chars and correct parsing */
627  *o = tmp;
628  s += 2; /* Will be incremented once more when we break out */
629  } else /* all other cases, just copy */
630  *o = *s;
631  }
632  *o = '\0';
633 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int tmp()
Definition: bt_open.c:389
#define AST_URI_LEGACY_SPACE
Definition: utils.h:342

◆ ast_uri_encode()

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 577 of file main/utils.c.

References ast_test_flag, AST_URI_ALPHANUM, AST_URI_LEGACY_SPACE, AST_URI_MARK, AST_URI_SIP_USER_UNRESERVED, out, and string.

Referenced by add_diversion(), add_rpid(), ast_ari_bridges_record(), ast_ari_channels_record(), AST_TEST_DEFINE(), build_contact(), config_curl(), destroy_curl(), initreqprep(), launch_asyncagi(), realtime_curl(), realtime_multi_curl(), require_curl(), store_curl(), update2_curl(), update_curl(), and uriencode().

578 {
579  const char *ptr = string; /* Start with the string */
580  char *out = outbuf;
581  const char *mark = "-_.!~*'()"; /* no encode set, RFC 2396 section 2.3, RFC 3261 sec 25 */
582  const char *user_unreserved = "&=+$,;?/"; /* user-unreserved set, RFC 3261 sec 25 */
583 
584  while (*ptr && out - outbuf < buflen - 1) {
585  if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *ptr == ' ') {
586  /* for legacy encoding, encode spaces as '+' */
587  *out = '+';
588  out++;
589  } else if (!(ast_test_flag(&spec, AST_URI_MARK)
590  && strchr(mark, *ptr))
591  && !(ast_test_flag(&spec, AST_URI_ALPHANUM)
592  && ((*ptr >= '0' && *ptr <= '9')
593  || (*ptr >= 'A' && *ptr <= 'Z')
594  || (*ptr >= 'a' && *ptr <= 'z')))
596  && strchr(user_unreserved, *ptr))) {
597 
598  if (out - outbuf >= buflen - 3) {
599  break;
600  }
601  out += sprintf(out, "%%%02hhX", (unsigned char) *ptr);
602  } else {
603  *out = *ptr; /* Continue copying the string */
604  out++;
605  }
606  ptr++;
607  }
608 
609  if (buflen) {
610  *out = '\0';
611  }
612 
613  return outbuf;
614 }
#define AST_URI_ALPHANUM
Definition: utils.h:339
#define ast_test_flag(p, flag)
Definition: utils.h:63
const char * string
Definition: presencestate.c:71
#define AST_URI_MARK
Definition: utils.h:340
#define AST_URI_SIP_USER_UNRESERVED
Definition: utils.h:344
FILE * out
Definition: utils/frame.c:33
#define AST_URI_LEGACY_SPACE
Definition: utils.h:342

◆ ast_utils_init()

int ast_utils_init ( void  )

Definition at line 2369 of file main/utils.c.

References ARRAY_LEN, ast_cli_register_multiple, ast_register_cleanup(), base64_init(), and utils_shutdown().

Referenced by asterisk_daemon().

2370 {
2371  dev_urandom_fd = open("/dev/urandom", O_RDONLY);
2372  base64_init();
2373 #ifdef DEBUG_THREADS
2374 #if !defined(LOW_MEMORY)
2376 #endif
2377 #endif
2379  return 0;
2380 }
static int dev_urandom_fd
Definition: main/utils.c:792
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void base64_init(void)
Definition: main/utils.c:538
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
static void utils_shutdown(void)
Definition: main/utils.c:2360
static struct ast_cli_entry utils_cli[]
Definition: main/utils.c:1369

◆ ast_utils_which()

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 2522 of file main/utils.c.

References ast_strdupa, NULL, and strsep().

2523 {
2524  const char *envPATH = getenv("PATH");
2525  char *tpath, *path;
2526  struct stat unused;
2527  if (!envPATH) {
2528  return NULL;
2529  }
2530  tpath = ast_strdupa(envPATH);
2531  while ((path = strsep(&tpath, ":"))) {
2532  snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
2533  if (!stat(fullpath, &unused)) {
2534  return fullpath;
2535  }
2536  }
2537  return NULL;
2538 }
#define NULL
Definition: resample.c:96
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * strsep(char **str, const char *delims)

◆ ast_wait_for_input()

int ast_wait_for_input ( int  fd,
int  ms 
)

Definition at line 1519 of file main/utils.c.

References ast_poll.

Referenced by action_waitevent(), ast_ari_websocket_session_read(), ast_iostream_wait_for_input(), ast_iostream_write(), ast_tcptls_server_root(), dahdi_test_timer(), get_input(), iostream_read(), moh_class_destructor(), sip_tcptls_read(), sip_websocket_callback(), and unbound_resolver_thread().

1520 {
1521  struct pollfd pfd[1];
1522 
1523  memset(pfd, 0, sizeof(pfd));
1524  pfd[0].fd = fd;
1525  pfd[0].events = POLLIN | POLLPRI;
1526  return ast_poll(pfd, 1, ms);
1527 }
#define ast_poll(a, b, c)
Definition: poll-compat.h:88

◆ ast_wait_for_output()

int ast_wait_for_output ( int  fd,
int  ms 
)

Definition at line 1529 of file main/utils.c.

References ast_poll.

Referenced by ast_iostream_write(), and iostream_read().

1530 {
1531  struct pollfd pfd[1];
1532 
1533  memset(pfd, 0, sizeof(pfd));
1534  pfd[0].fd = fd;
1535  pfd[0].events = POLLOUT;
1536  return ast_poll(pfd, 1, ms);
1537 }
#define ast_poll(a, b, c)
Definition: poll-compat.h:88

◆ ast_xml_escape()

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
Returns
0 for success
-1 if buflen is too short.

Definition at line 718 of file main/utils.c.

References ast_assert, end, entity, len(), NULL, and string.

Referenced by ast_http_create_response(), state_notify_build_xml(), and test_xml().

719 {
720  char *dst = outbuf;
721  char *end = outbuf + buflen - 1; /* save one for the null terminator */
722 
723  /* Handle the case for the empty output buffer */
724  if (buflen == 0) {
725  return -1;
726  }
727 
728  /* Escaping rules from http://www.w3.org/TR/REC-xml/#syntax */
729  /* This also prevents partial entities at the end of a string */
730  while (*string && dst < end) {
731  const char *entity = NULL;
732  int len = 0;
733 
734  switch (*string) {
735  case '<':
736  entity = "&lt;";
737  len = 4;
738  break;
739  case '&':
740  entity = "&amp;";
741  len = 5;
742  break;
743  case '>':
744  /* necessary if ]]> is in the string; easier to escape them all */
745  entity = "&gt;";
746  len = 4;
747  break;
748  case '\'':
749  /* necessary in single-quoted strings; easier to escape them all */
750  entity = "&apos;";
751  len = 6;
752  break;
753  case '"':
754  /* necessary in double-quoted strings; easier to escape them all */
755  entity = "&quot;";
756  len = 6;
757  break;
758  default:
759  *dst++ = *string++;
760  break;
761  }
762 
763  if (entity) {
764  ast_assert(len == strlen(entity));
765  if (end - dst < len) {
766  /* no room for the entity; stop */
767  break;
768  }
769  /* just checked for length; strcpy is fine */
770  strcpy(dst, entity);
771  dst += len;
772  ++string;
773  }
774  }
775  /* Write null terminator */
776  *dst = '\0';
777  /* If any chars are left in string, return failure */
778  return *string == '\0' ? 0 : -1;
779 }
static int entity
Definition: isdn_lib.c:259
#define ast_assert(a)
Definition: utils.h:695
const char * string
Definition: presencestate.c:71
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ base64_init()

static void base64_init ( void  )
static

Definition at line 538 of file main/utils.c.

References b2a, b2a_url, base64, and base64url.

Referenced by ast_utils_init().

539 {
540  int x;
541  memset(b2a, -1, sizeof(b2a));
542  memset(b2a_url, -1, sizeof(b2a_url));
543  /* Initialize base-64 Conversion table */
544  for (x = 0; x < 26; x++) {
545  /* A-Z */
546  base64[x] = 'A' + x;
547  base64url[x] = 'A' + x;
548  b2a['A' + x] = x;
549  b2a_url['A' + x] = x;
550  /* a-z */
551  base64[x + 26] = 'a' + x;
552  base64url[x + 26] = 'a' + x;
553  b2a['a' + x] = x + 26;
554  b2a_url['a' + x] = x + 26;
555  /* 0-9 */
556  if (x < 10) {
557  base64[x + 52] = '0' + x;
558  base64url[x + 52] = '0' + x;
559  b2a['0' + x] = x + 52;
560  b2a_url['0' + x] = x + 52;
561  }
562  }
563  base64[62] = '+';
564  base64[63] = '/';
565  base64url[62] = '-';
566  base64url[63] = '_';
567  b2a[(int)'+'] = 62;
568  b2a[(int)'/'] = 63;
569  b2a_url[(int)'-'] = 62;
570  b2a_url[(int)'_'] = 63;
571 }
static char b2a_url[256]
Definition: main/utils.c:81
static char b2a[256]
Definition: main/utils.c:80
static char base64url[64]
Definition: main/utils.c:79
static char base64[64]
Definition: main/utils.c:78

◆ dummy_start()

static void* dummy_start ( void *  data)
static

Definition at line 1394 of file main/utils.c.

References ast_free, ast_get_tid(), AST_LIST_INSERT_TAIL, AST_MUTEX_KIND, ast_register_thread(), ast_strdup, ast_threadstorage_get(), ast_unregister_thread(), thr_arg::data, thr_lock_info::lock, lock_info, lock_infos_lock, thr_lock_info::lwp, ast_mutex_info::mutex, thr_arg::name, NULL, pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock, thr_arg::start_routine, thr_lock_info::thread_id, thread_lock_info, and thr_lock_info::thread_name.

Referenced by ast_pthread_create_stack().

1395 {
1396  void *ret;
1397  struct thr_arg a = *((struct thr_arg *) data); /* make a local copy */
1398 #ifdef DEBUG_THREADS
1399  struct thr_lock_info *lock_info;
1400  pthread_mutexattr_t mutex_attr;
1401 
1402  if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
1403  return NULL;
1404 
1405  lock_info->thread_id = pthread_self();
1406  lock_info->lwp = ast_get_tid();
1407  lock_info->thread_name = ast_strdup(a.name);
1408 
1409  pthread_mutexattr_init(&mutex_attr);
1410  pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
1411  pthread_mutex_init(&lock_info->lock, &mutex_attr);
1412  pthread_mutexattr_destroy(&mutex_attr);
1413 
1414  pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
1415  AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
1416  pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
1417 #endif /* DEBUG_THREADS */
1418 
1419  /* note that even though data->name is a pointer to allocated memory,
1420  we are not freeing it here because ast_register_thread is going to
1421  keep a copy of the pointer and then ast_unregister_thread will
1422  free the memory
1423  */
1424  ast_free(data);
1426  pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
1427 
1428  ret = a.start_routine(a.data);
1429 
1430  pthread_cleanup_pop(1);
1431 
1432  return ret;
1433 }
#define pthread_mutex_init
Definition: lock.h:626
void ast_register_thread(char *name)
Definition: asterisk.c:414
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
int ast_get_tid(void)
Get current thread ID.
Definition: main/utils.c:2504
static struct ast_threadstorage thread_lock_info
Definition: main/utils.c:902
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void ast_unregister_thread(void *id)
Definition: asterisk.c:430
static ast_mutex_t lock_infos_lock
Locked when accessing the lock_infos list.
Definition: main/utils.c:853
#define pthread_mutex_lock
Definition: lock.h:623
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
pthread_mutex_t lock
Definition: main/utils.c:846
pthread_t thread_id
Definition: main/utils.c:818
#define ast_free(a)
Definition: astmm.h:182
const char * thread_name
Definition: main/utils.c:820
void *(* start_routine)(void *)
Definition: main/utils.c:1382
A list of each thread&#39;s lock info.
Definition: main/utils.c:857
void * data
Definition: main/utils.c:1383
Keep track of which locks a thread holds.
Definition: main/utils.c:816
pthread_mutex_t mutex
Definition: lock.h:136
Definition: search.h:40
char * name
Definition: main/utils.c:1384
#define pthread_mutex_unlock
Definition: lock.h:624
#define AST_MUTEX_KIND
Definition: lock.h:77
static struct test_val a

◆ escape_alloc()

static char* escape_alloc ( const char *  s,
size_t *  size 
)
static

Definition at line 1870 of file main/utils.c.

References ast_malloc, and NULL.

Referenced by ast_escape_alloc(), and ast_escape_c_alloc().

1871 {
1872  if (!s) {
1873  return NULL;
1874  }
1875 
1876  /*
1877  * The result string needs to be twice the size of the given
1878  * string just in case every character in it needs to be escaped.
1879  */
1880  *size = strlen(s) * 2 + 1;
1881  return ast_malloc(*size);
1882 }
#define NULL
Definition: resample.c:96
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193

◆ handle_show_locks()

static char* handle_show_locks ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1339 of file main/utils.c.

References ast_cli(), ast_cli_allow_at_shutdown(), ast_dump_locks(), ast_free, ast_str_buffer(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, str, and ast_cli_entry::usage.

1340 {
1341  struct ast_str *str;
1342 
1343  switch (cmd) {
1344  case CLI_INIT:
1345  e->command = "core show locks";
1346  e->usage =
1347  "Usage: core show locks\n"
1348  " This command is for lock debugging. It prints out which locks\n"
1349  "are owned by each active thread.\n";
1351  return NULL;
1352 
1353  case CLI_GENERATE:
1354  return NULL;
1355  }
1356 
1357  str = ast_dump_locks();
1358  if (!str) {
1359  return CLI_FAILURE;
1360  }
1361 
1362  ast_cli(a->fd, "%s", ast_str_buffer(str));
1363 
1364  ast_free(str);
1365 
1366  return CLI_SUCCESS;
1367 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Definition: cli.h:152
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
int ast_cli_allow_at_shutdown(struct ast_cli_entry *e)
Definition: main/cli.c:3026
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define CLI_FAILURE
Definition: cli.h:46
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
struct ast_str * ast_dump_locks(void)
Generate a lock dump equivalent to "core show locks".
Definition: main/utils.c:1264

◆ lock_info_destroy()

static void lock_info_destroy ( void *  data)
static

Destroy a thread's lock info.

This gets called automatically when the thread stops

Definition at line 864 of file main/utils.c.

References ast_free, AST_LIST_REMOVE, ast_log, thr_lock_info::file, thr_lock_info::func, thr_lock_info::line_num, thr_lock_info::lock, thr_lock_info::lock_addr, lock_info, lock_infos_lock, thr_lock_info::lock_name, thr_lock_info::locks, LOG_ERROR, ast_mutex_info::mutex, thr_lock_info::num_locks, thr_lock_info::pending, pthread_mutex_destroy, pthread_mutex_lock, pthread_mutex_unlock, and thr_lock_info::thread_name.

865 {
866  struct thr_lock_info *lock_info = data;
867  int i;
868 
870  AST_LIST_REMOVE(&lock_infos, lock_info, entry);
872 
873 
874  for (i = 0; i < lock_info->num_locks; i++) {
875  if (lock_info->locks[i].pending == -1) {
876  /* This just means that the last lock this thread went for was by
877  * using trylock, and it failed. This is fine. */
878  break;
879  }
880 
882  "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n",
883  lock_info->thread_name,
884  lock_info->locks[i].lock_name,
885  lock_info->locks[i].lock_addr,
886  lock_info->locks[i].func,
887  lock_info->locks[i].file,
888  lock_info->locks[i].line_num
889  );
890  }
891 
892  pthread_mutex_destroy(&lock_info->lock);
893  if (lock_info->thread_name) {
894  ast_free((void *) lock_info->thread_name);
895  }
896  ast_free(lock_info);
897 }
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
const char * lock_name
Definition: main/utils.c:825
unsigned int num_locks
Definition: main/utils.c:841
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
void * lock_addr
Definition: main/utils.c:826
#define pthread_mutex_destroy
Definition: lock.h:627
#define ast_log
Definition: astobj2.c:42
static ast_mutex_t lock_infos_lock
Locked when accessing the lock_infos list.
Definition: main/utils.c:853
#define pthread_mutex_lock
Definition: lock.h:623
const char * func
Definition: main/utils.c:824
static const struct ast_datastore_info lock_info
Definition: func_lock.c:115
#define LOG_ERROR
Definition: logger.h:285
pthread_mutex_t lock
Definition: main/utils.c:846
const char * file
Definition: main/utils.c:823
#define ast_free(a)
Definition: astmm.h:182
const char * thread_name
Definition: main/utils.c:820
A list of each thread&#39;s lock info.
Definition: main/utils.c:857
Keep track of which locks a thread holds.
Definition: main/utils.c:816
pthread_mutex_t mutex
Definition: lock.h:136
Definition: search.h:40
#define pthread_mutex_unlock
Definition: lock.h:624

◆ locktype2str()

static const char* locktype2str ( enum ast_lock_type  type)
static

Definition at line 1132 of file main/utils.c.

References AST_MUTEX, AST_RDLOCK, and AST_WRLOCK.

Referenced by append_lock_information().

1133 {
1134  switch (type) {
1135  case AST_MUTEX:
1136  return "MUTEX";
1137  case AST_RDLOCK:
1138  return "RDLOCK";
1139  case AST_WRLOCK:
1140  return "WRLOCK";
1141  }
1142 
1143  return "UNKNOWN";
1144 }
static const char type[]
Definition: chan_ooh323.c:109

◆ safe_mkdir()

static int safe_mkdir ( const char *  base_path,
char *  path,
int  mode 
)
static

Definition at line 2266 of file main/utils.c.

References ast_assert, ast_begins_with(), ast_std_free(), c, errno, NULL, and RAII_VAR.

Referenced by ast_safe_mkdir().

2267 {
2268  RAII_VAR(char *, absolute_path, NULL, ast_std_free);
2269 
2270  absolute_path = realpath(path, NULL);
2271 
2272  if (absolute_path) {
2273  /* Path exists, but is it in the right place? */
2274  if (!ast_begins_with(absolute_path, base_path)) {
2275  return EPERM;
2276  }
2277 
2278  /* It is in the right place! */
2279  return 0;
2280  } else {
2281  /* Path doesn't exist. */
2282 
2283  /* The slash terminating the subpath we're checking */
2284  char *path_term = strchr(path, '/');
2285  /* True indicates the parent path is within base_path */
2286  int parent_is_safe = 0;
2287  int res;
2288 
2289  while (path_term) {
2290  RAII_VAR(char *, absolute_subpath, NULL, ast_std_free);
2291 
2292  /* Truncate the path one past the slash */
2293  char c = *(path_term + 1);
2294  *(path_term + 1) = '\0';
2295  absolute_subpath = realpath(path, NULL);
2296 
2297  if (absolute_subpath) {
2298  /* Subpath exists, but is it safe? */
2299  parent_is_safe = ast_begins_with(
2300  absolute_subpath, base_path);
2301  } else if (parent_is_safe) {
2302  /* Subpath does not exist, but parent is safe
2303  * Create it */
2304  res = mkdir(path, mode);
2305  if (res != 0) {
2306  ast_assert(errno != EEXIST);
2307  return errno;
2308  }
2309  } else {
2310  /* Subpath did not exist, parent was not safe
2311  * Fail! */
2312  errno = EPERM;
2313  return errno;
2314  }
2315  /* Restore the path */
2316  *(path_term + 1) = c;
2317  /* Move on to the next slash */
2318  path_term = strchr(path_term + 1, '/');
2319  }
2320 
2321  /* Now to build the final path, but only if it's safe */
2322  if (!parent_is_safe) {
2323  errno = EPERM;
2324  return errno;
2325  }
2326 
2327  res = mkdir(path, mode);
2328  if (res != 0 && errno != EEXIST) {
2329  return errno;
2330  }
2331 
2332  return 0;
2333  }
2334 }
void ast_std_free(void *ptr)
Definition: astmm.c:1766
#define ast_assert(a)
Definition: utils.h:695
static struct test_val c
#define NULL
Definition: resample.c:96
#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:911
int errno
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Definition: strings.h:94

◆ tvfix()

static struct timeval tvfix ( struct timeval  a)
static

Definition at line 1990 of file main/utils.c.

References a, ast_log, LOG_WARNING, and ONE_MILLION.

Referenced by ast_tvadd(), and ast_tvsub().

1991 {
1992  if (a.tv_usec >= ONE_MILLION) {
1993  ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
1994  (long)a.tv_sec, (long int) a.tv_usec);
1995  a.tv_sec += a.tv_usec / ONE_MILLION;
1996  a.tv_usec %= ONE_MILLION;
1997  } else if (a.tv_usec < 0) {
1998  ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
1999  (long)a.tv_sec, (long int) a.tv_usec);
2000  a.tv_usec = 0;
2001  }
2002  return a;
2003 }
#define ONE_MILLION
Definition: main/utils.c:1985
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
static struct test_val a

◆ utils_shutdown()

static void utils_shutdown ( void  )
static

Definition at line 2360 of file main/utils.c.

References ARRAY_LEN, and ast_cli_unregister_multiple().

Referenced by ast_utils_init().

2361 {
2362  close(dev_urandom_fd);
2363  dev_urandom_fd = -1;
2364 #if defined(DEBUG_THREADS) && !defined(LOW_MEMORY)
2366 #endif
2367 }
static int dev_urandom_fd
Definition: main/utils.c:792
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static struct ast_cli_entry utils_cli[]
Definition: main/utils.c:1369

◆ wait_for_output()

static int wait_for_output ( int  fd,
int  timeoutms 
)
static

Definition at line 1539 of file main/utils.c.

References ast_debug, ast_log, ast_poll, ast_tvdiff_ms(), ast_tvnow(), errno, and LOG_ERROR.

Referenced by ast_carefulwrite().

1540 {
1541  struct pollfd pfd = {
1542  .fd = fd,
1543  .events = POLLOUT,
1544  };
1545  int res;
1546  struct timeval start = ast_tvnow();
1547  int elapsed = 0;
1548 
1549  /* poll() until the fd is writable without blocking */
1550  while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
1551  if (res == 0) {
1552  /* timed out. */
1553 #ifndef STANDALONE
1554  ast_debug(1, "Timed out trying to write\n");
1555 #endif
1556  return -1;
1557  } else if (res == -1) {
1558  /* poll() returned an error, check to see if it was fatal */
1559 
1560  if (errno == EINTR || errno == EAGAIN) {
1561  elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1562  if (elapsed >= timeoutms) {
1563  return -1;
1564  }
1565  /* This was an acceptable error, go back into poll() */
1566  continue;
1567  }
1568 
1569  /* Fatal error, bail. */
1570  ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
1571 
1572  return -1;
1573  }
1574  elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1575  if (elapsed >= timeoutms) {
1576  return -1;
1577  }
1578  }
1579 
1580  return 0;
1581 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
#define LOG_ERROR
Definition: logger.h:285
int errno

Variable Documentation

◆ ast_uri_http

const struct ast_flags ast_uri_http = {AST_URI_UNRESERVED}

◆ ast_uri_http_legacy

const struct ast_flags ast_uri_http_legacy = {AST_URI_LEGACY_SPACE | AST_URI_UNRESERVED}

◆ ast_uri_sip_user

const struct ast_flags ast_uri_sip_user = {AST_URI_UNRESERVED | AST_URI_SIP_USER_UNRESERVED}

◆ b2a

char b2a[256]
static

Definition at line 80 of file main/utils.c.

Referenced by ast_base64decode(), and base64_init().

◆ b2a_url

char b2a_url[256]
static

Definition at line 81 of file main/utils.c.

Referenced by ast_base64url_decode(), and base64_init().

◆ base64

char base64[64]
static

◆ base64url

char base64url[64]
static

Definition at line 79 of file main/utils.c.

Referenced by ast_base64url_encode_full(), and base64_init().

◆ dev_urandom_fd

int dev_urandom_fd = -1
static

Definition at line 792 of file main/utils.c.

Referenced by ast_uuid_init().

◆ escape_sequences

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

Definition at line 1774 of file main/utils.c.

Referenced by ast_escape(), and ast_escape_c().

◆ escape_sequences_map

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

Definition at line 1782 of file main/utils.c.

◆ inet_ntoa_buf

struct ast_threadstorage inet_ntoa_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_inet_ntoa_buf , .custom_init = NULL , }
static

Definition at line 83 of file main/utils.c.

Referenced by ast_inet_ntoa().

◆ lock_infos

struct lock_infos lock_infos = { .first = NULL, .last = NULL, }
static

◆ lock_infos_lock

ast_mutex_t lock_infos_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Locked when accessing the lock_infos list.

Definition at line 853 of file main/utils.c.

Referenced by ast_dump_locks(), ast_log_show_lock(), dummy_start(), and lock_info_destroy().

◆ randomlock

ast_mutex_t randomlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 2061 of file main/utils.c.

Referenced by ast_random().

◆ thread_lock_info

struct ast_threadstorage thread_lock_info = { .once = PTHREAD_ONCE_INIT , .key_init = __init_thread_lock_info , .custom_init = NULL , }
static

◆ thread_user_interface_tl

struct ast_threadstorage thread_user_interface_tl = { .once = PTHREAD_ONCE_INIT , .key_init = __init_thread_user_interface_tl , .custom_init = NULL , }
static

Definition at line 2979 of file main/utils.c.

Referenced by ast_thread_is_user_interface(), and ast_thread_user_interface_set().

◆ utils_cli

struct ast_cli_entry utils_cli[]
static
Initial value:
= {
{ .handler = handle_show_locks , .summary = "Show which locks are held by which thread" ,},
}
static char * handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/utils.c:1339

Definition at line 1369 of file main/utils.c.