Utility functions. More...
#include "asterisk.h"#include <ctype.h>#include <sys/stat.h>#include <fcntl.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/strings.h"#include "asterisk/time.h"#include "asterisk/stringfields.h"#include "asterisk/utils.h"#include "asterisk/threadstorage.h"#include "asterisk/config.h"
Go to the source code of this file.
Data Structures | |
| struct | thr_arg |
Defines | |
| #define | ALLOCATOR_OVERHEAD 48 |
| #define | AST_API_MODULE |
| #define | AST_API_MODULE |
| #define | AST_API_MODULE |
| #define | AST_API_MODULE |
| #define | AST_API_MODULE |
| #define | AST_API_MODULE |
| #define | AST_API_MODULE |
| #define | ONE_MILLION 1000000 |
Functions | |
| void * | __ast_calloc_with_stringfields (unsigned int num_structs, size_t struct_size, size_t field_mgr_offset, size_t field_mgr_pool_offset, size_t pool_size, const char *file, int lineno, const char *func) |
| ast_string_field | __ast_string_field_alloc_space (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t needed) |
| int | __ast_string_field_init (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, int needed, const char *file, int lineno, const char *func) |
| void | __ast_string_field_ptr_build (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, ast_string_field *ptr, const char *format,...) |
| void | __ast_string_field_ptr_build_va (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, ast_string_field *ptr, const char *format, va_list ap1, va_list ap2) |
| int | __ast_string_field_ptr_grow (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t needed, const ast_string_field *ptr) |
| void | __ast_string_field_release_active (struct ast_string_field_pool *pool_head, const ast_string_field ptr) |
| static void | __init_inet_ntoa_buf (void) |
| static int | add_string_pool (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t size, const char *file, int lineno, const char *func) |
| add a new block to the pool. We can only allocate from the topmost pool, so the fields in *mgr reflect the size of that only. | |
| int | ast_atomic_fetchadd_int_slow (volatile int *p, int v) |
| int | ast_base64decode (unsigned char *dst, const char *src, int max) |
| decode BASE64 encoded text | |
| int | ast_base64encode (char *dst, const unsigned char *src, int srclen, int max) |
| Encode data in base64. | |
| int | ast_base64encode_full (char *dst, const unsigned char *src, int srclen, int max, int linebreaks) |
| encode text to BASE64 coding | |
| int | ast_build_string (char **buffer, size_t *space, const char *fmt,...) |
| Build a string in a buffer, designed to be called repeatedly. | |
| 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. | |
| int | ast_careful_fwrite (FILE *f, int fd, const char *src, size_t len, int timeoutms) |
| Write data to a file stream with a timeout. | |
| 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. | |
| void | ast_do_crash (void) |
| Force a crash if DO_CRASH is defined. | |
| void | ast_enable_packet_fragmentation (int sock) |
| Disable PMTU discovery on a socket. | |
| char * | ast_escape_quoted (const char *string, char *outbuf, int buflen) |
| escapes characters specified for quoted portions of sip messages | |
| 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". | |
| int | ast_get_time_t (const char *src, time_t *dst, time_t _default, int *consumed) |
| get values from config variables. | |
| int | ast_get_timeval (const char *src, struct timeval *dst, struct timeval _default, int *consumed) |
| get values from config variables. | |
| 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). | |
| const char * | ast_inet_ntoa (struct in_addr ia) |
| ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa | |
| void | ast_join (char *s, size_t len, const char *const w[]) |
| void | ast_md5_hash (char *output, const char *input) |
| Produce 32 char MD5 hash of value. | |
| int | ast_mkdir (const char *path, int mode) |
| Recursively create directory path. | |
| int | ast_parse_digest (const char *digest, struct ast_http_digest *d, int request, int pedantic) |
| Parse digest authorization header. | |
| char * | ast_process_quotes_and_slashes (char *start, char find, char replace_with) |
| Process a string to find and replace characters. | |
| 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_remaining_ms (struct timeval start, int max_ms) |
| Calculate remaining milliseconds given a starting timestamp and upper bound. | |
| void | ast_sha1_hash (char *output, const char *input) |
| Produce 40 char SHA1 hash of value. | |
| char * | ast_strip_quoted (char *s, const char *beg_quotes, const char *end_quotes) |
| Strip leading/trailing whitespace and quotes from a string. | |
| 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". | |
| struct timeval | ast_tvadd (struct timeval a, struct timeval b) |
| Returns the sum of two timevals a + b. | |
| struct timeval | ast_tvsub (struct timeval a, struct timeval b) |
| Returns the difference of two timevals a - b. | |
| char * | ast_unescape_c (char *src) |
| Convert some C escape sequences. | |
| char * | ast_unescape_semicolon (char *s) |
| Strip backslash for "escaped" semicolons, the string to be stripped (will be modified). | |
| void | ast_uri_decode (char *s) |
| ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string) | |
| char * | ast_uri_encode (const char *string, char *outbuf, int buflen, int do_special_char) |
| Turn text string to URI-encoded XX version. | |
| 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. | |
| int | ast_wait_for_input (int fd, int ms) |
| static int | ast_wait_for_output (int fd, int timeoutms) |
| int | ast_xml_escape (const char *string, char *const outbuf, const size_t buflen) |
| Escape reserved characters for use in XML. | |
| static void | base64_init (void) |
| static void * | dummy_start (void *data) |
| static size_t | optimal_alloc_size (size_t size) |
| static struct timeval | tvfix (struct timeval a) |
Variables | |
| ast_string_field | __ast_string_field_empty = __ast_string_field_empty_buffer.string |
| struct { | |
| ast_string_field_allocation allocation | |
| char string [1] | |
| } | __ast_string_field_empty_buffer |
| static char | b2a [256] |
| static char | base64 [64] |
| static int | dev_urandom_fd |
| static ast_mutex_t | fetchadd_m = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
| static struct ast_threadstorage | inet_ntoa_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_inet_ntoa_buf , .custom_init = NULL , } |
| static ast_mutex_t | randomlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
| glibc puts a lock inside random(3), so that the results are thread-safe. BSD libc (and others) do not. | |
Utility functions.
Definition in file utils.c.
| #define ALLOCATOR_OVERHEAD 48 |
Definition at line 1680 of file utils.c.
Referenced by optimal_alloc_size().
| #define ONE_MILLION 1000000 |
Definition at line 1520 of file utils.c.
Referenced by ast_tvadd(), ast_tvsub(), and tvfix().
| void* __ast_calloc_with_stringfields | ( | unsigned int | num_structs, | |
| size_t | struct_size, | |||
| size_t | field_mgr_offset, | |||
| size_t | field_mgr_pool_offset, | |||
| size_t | pool_size, | |||
| const char * | file, | |||
| int | lineno, | |||
| const char * | func | |||
| ) |
Definition at line 1959 of file utils.c.
References __ast_calloc(), allocation, ast_calloc, ast_string_field_pool::base, ast_string_field_mgr::embedded_pool, optimal_alloc_size(), ast_string_field_mgr::owner_file, ast_string_field_mgr::owner_func, ast_string_field_mgr::owner_line, and ast_string_field_pool::size.
01962 { 01963 struct ast_string_field_mgr *mgr; 01964 struct ast_string_field_pool *pool; 01965 struct ast_string_field_pool **pool_head; 01966 size_t pool_size_needed = sizeof(*pool) + pool_size; 01967 size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed); 01968 void *allocation; 01969 unsigned int x; 01970 01971 #if defined(__AST_DEBUG_MALLOC) 01972 if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) { 01973 return NULL; 01974 } 01975 #else 01976 if (!(allocation = ast_calloc(num_structs, size_to_alloc))) { 01977 return NULL; 01978 } 01979 #endif 01980 01981 for (x = 0; x < num_structs; x++) { 01982 void *base = allocation + (size_to_alloc * x); 01983 const char **p; 01984 01985 mgr = base + field_mgr_offset; 01986 pool_head = base + field_mgr_pool_offset; 01987 pool = base + struct_size; 01988 01989 p = (const char **) pool_head + 1; 01990 while ((struct ast_string_field_mgr *) p != mgr) { 01991 *p++ = __ast_string_field_empty; 01992 } 01993 01994 mgr->embedded_pool = pool; 01995 *pool_head = pool; 01996 pool->size = size_to_alloc - struct_size - sizeof(*pool); 01997 #if defined(__AST_DEBUG_MALLOC) 01998 mgr->owner_file = file; 01999 mgr->owner_func = func; 02000 mgr->owner_line = lineno; 02001 #endif 02002 } 02003 02004 return allocation; 02005 }
| ast_string_field __ast_string_field_alloc_space | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| size_t | needed | |||
| ) |
Definition at line 1800 of file utils.c.
References add_string_pool(), ast_alignof, ast_assert, ast_make_room_for, AST_STRING_FIELD_ALLOCATION, ast_string_field_mgr::last_alloc, ast_string_field_mgr::owner_file, ast_string_field_mgr::owner_func, and ast_string_field_mgr::owner_line.
Referenced by __ast_string_field_ptr_build_va().
01802 { 01803 char *result = NULL; 01804 size_t space = (*pool_head)->size - (*pool_head)->used; 01805 size_t to_alloc; 01806 01807 /* Make room for ast_string_field_allocation and make it a multiple of that. */ 01808 to_alloc = ast_make_room_for(needed, ast_string_field_allocation); 01809 ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0); 01810 01811 if (__builtin_expect(to_alloc > space, 0)) { 01812 size_t new_size = (*pool_head)->size; 01813 01814 while (new_size < to_alloc) { 01815 new_size *= 2; 01816 } 01817 01818 #if defined(__AST_DEBUG_MALLOC) 01819 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func)) 01820 return NULL; 01821 #else 01822 if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__)) 01823 return NULL; 01824 #endif 01825 } 01826 01827 /* pool->base is always aligned (gcc aligned attribute). We ensure that 01828 * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation) 01829 * causing result to always be aligned as well; which in turn fixes that 01830 * AST_STRING_FIELD_ALLOCATION(result) is aligned. */ 01831 result = (*pool_head)->base + (*pool_head)->used; 01832 (*pool_head)->used += to_alloc; 01833 (*pool_head)->active += needed; 01834 result += ast_alignof(ast_string_field_allocation); 01835 AST_STRING_FIELD_ALLOCATION(result) = needed; 01836 mgr->last_alloc = result; 01837 01838 return result; 01839 }
| int __ast_string_field_init | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| int | needed, | |||
| const char * | file, | |||
| int | lineno, | |||
| const char * | func | |||
| ) |
Definition at line 1733 of file utils.c.
References ast_string_field_pool::active, add_string_pool(), ast_free, ast_log(), ast_string_field_mgr::embedded_pool, ast_string_field_mgr::last_alloc, LOG_WARNING, ast_string_field_mgr::owner_file, ast_string_field_mgr::owner_func, ast_string_field_mgr::owner_line, ast_string_field_pool::prev, and ast_string_field_pool::used.
01735 { 01736 const char **p = (const char **) pool_head + 1; 01737 struct ast_string_field_pool *cur = NULL; 01738 struct ast_string_field_pool *preserve = NULL; 01739 01740 /* clear fields - this is always necessary */ 01741 while ((struct ast_string_field_mgr *) p != mgr) { 01742 *p++ = __ast_string_field_empty; 01743 } 01744 01745 mgr->last_alloc = NULL; 01746 #if defined(__AST_DEBUG_MALLOC) 01747 mgr->owner_file = file; 01748 mgr->owner_func = func; 01749 mgr->owner_line = lineno; 01750 #endif 01751 if (needed > 0) { /* allocate the initial pool */ 01752 *pool_head = NULL; 01753 mgr->embedded_pool = NULL; 01754 return add_string_pool(mgr, pool_head, needed, file, lineno, func); 01755 } 01756 01757 /* if there is an embedded pool, we can't actually release *all* 01758 * pools, we must keep the embedded one. if the caller is about 01759 * to free the structure that contains the stringfield manager 01760 * and embedded pool anyway, it will be freed as part of that 01761 * operation. 01762 */ 01763 if ((needed < 0) && mgr->embedded_pool) { 01764 needed = 0; 01765 } 01766 01767 if (needed < 0) { /* reset all pools */ 01768 cur = *pool_head; 01769 } else if (mgr->embedded_pool) { /* preserve the embedded pool */ 01770 preserve = mgr->embedded_pool; 01771 cur = *pool_head; 01772 } else { /* preserve the last pool */ 01773 if (*pool_head == NULL) { 01774 ast_log(LOG_WARNING, "trying to reset empty pool\n"); 01775 return -1; 01776 } 01777 preserve = *pool_head; 01778 cur = preserve->prev; 01779 } 01780 01781 if (preserve) { 01782 preserve->prev = NULL; 01783 preserve->used = preserve->active = 0; 01784 } 01785 01786 while (cur) { 01787 struct ast_string_field_pool *prev = cur->prev; 01788 01789 if (cur != preserve) { 01790 ast_free(cur); 01791 } 01792 cur = prev; 01793 } 01794 01795 *pool_head = preserve; 01796 01797 return 0; 01798 }
| void __ast_string_field_ptr_build | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| ast_string_field * | ptr, | |||
| const char * | format, | |||
| ... | ||||
| ) |
Definition at line 1944 of file utils.c.
References __ast_string_field_ptr_build_va().
01947 { 01948 va_list ap1, ap2; 01949 01950 va_start(ap1, format); 01951 va_start(ap2, format); /* va_copy does not exist on FreeBSD */ 01952 01953 __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2); 01954 01955 va_end(ap1); 01956 va_end(ap2); 01957 }
| void __ast_string_field_ptr_build_va | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| ast_string_field * | ptr, | |||
| const char * | format, | |||
| va_list | ap1, | |||
| va_list | ap2 | |||
| ) |
Definition at line 1884 of file utils.c.
References __ast_string_field_alloc_space(), __ast_string_field_release_active(), ast_align_for, ast_alignof, ast_make_room_for, AST_STRING_FIELD_ALLOCATION, available(), and ast_string_field_mgr::last_alloc.
Referenced by __ast_string_field_ptr_build().
01887 { 01888 size_t needed; 01889 size_t available; 01890 size_t space = (*pool_head)->size - (*pool_head)->used; 01891 ssize_t grow; 01892 char *target; 01893 01894 /* if the field already has space allocated, try to reuse it; 01895 otherwise, try to use the empty space at the end of the current 01896 pool 01897 */ 01898 if (*ptr != __ast_string_field_empty) { 01899 target = (char *) *ptr; 01900 available = AST_STRING_FIELD_ALLOCATION(*ptr); 01901 if (*ptr == mgr->last_alloc) { 01902 available += space; 01903 } 01904 } else { 01905 /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation) 01906 * so we don't need to re-align anything here. 01907 */ 01908 target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation); 01909 available = space - ast_alignof(ast_string_field_allocation); 01910 } 01911 01912 needed = vsnprintf(target, available, format, ap1) + 1; 01913 01914 if (needed > available) { 01915 /* the allocation could not be satisfied using the field's current allocation 01916 (if it has one), or the space available in the pool (if it does not). allocate 01917 space for it, adding a new string pool if necessary. 01918 */ 01919 if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) { 01920 return; 01921 } 01922 vsprintf(target, format, ap2); 01923 __ast_string_field_release_active(*pool_head, *ptr); 01924 *ptr = target; 01925 } else if (*ptr != target) { 01926 /* the allocation was satisfied using available space in the pool, but not 01927 using the space already allocated to the field 01928 */ 01929 __ast_string_field_release_active(*pool_head, *ptr); 01930 mgr->last_alloc = *ptr = target; 01931 AST_STRING_FIELD_ALLOCATION(target) = needed; 01932 (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation); 01933 (*pool_head)->active += needed; 01934 } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) { 01935 /* the allocation was satisfied by using available space in the pool *and* 01936 the field was the last allocated field from the pool, so it grew 01937 */ 01938 AST_STRING_FIELD_ALLOCATION(*ptr) += grow; 01939 (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation); 01940 (*pool_head)->active += grow; 01941 } 01942 }
| int __ast_string_field_ptr_grow | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| size_t | needed, | |||
| const ast_string_field * | ptr | |||
| ) |
Definition at line 1841 of file utils.c.
References AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.
01844 { 01845 ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr); 01846 size_t space = (*pool_head)->size - (*pool_head)->used; 01847 01848 if (*ptr != mgr->last_alloc) { 01849 return 1; 01850 } 01851 01852 if (space < grow) { 01853 return 1; 01854 } 01855 01856 (*pool_head)->used += grow; 01857 (*pool_head)->active += grow; 01858 AST_STRING_FIELD_ALLOCATION(*ptr) += grow; 01859 01860 return 0; 01861 }
| void __ast_string_field_release_active | ( | struct ast_string_field_pool * | pool_head, | |
| const ast_string_field | ptr | |||
| ) |
Definition at line 1863 of file utils.c.
References ast_string_field_pool::active, ast_free, AST_STRING_FIELD_ALLOCATION, and ast_string_field_pool::prev.
Referenced by __ast_string_field_ptr_build_va().
01865 { 01866 struct ast_string_field_pool *pool, *prev; 01867 01868 if (ptr == __ast_string_field_empty) { 01869 return; 01870 } 01871 01872 for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) { 01873 if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) { 01874 pool->active -= AST_STRING_FIELD_ALLOCATION(ptr); 01875 if ((pool->active == 0) && prev) { 01876 prev->prev = pool->prev; 01877 ast_free(pool); 01878 } 01879 break; 01880 } 01881 } 01882 }
| static int add_string_pool | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| size_t | size, | |||
| const char * | file, | |||
| int | lineno, | |||
| const char * | func | |||
| ) | [static] |
add a new block to the pool. We can only allocate from the topmost pool, so the fields in *mgr reflect the size of that only.
Definition at line 1697 of file utils.c.
References __ast_calloc(), ast_calloc, ast_string_field_mgr::last_alloc, optimal_alloc_size(), ast_string_field_pool::prev, and ast_string_field_pool::size.
Referenced by __ast_string_field_alloc_space(), and __ast_string_field_init().
01699 { 01700 struct ast_string_field_pool *pool; 01701 size_t alloc_size = optimal_alloc_size(sizeof(*pool) + size); 01702 01703 #if defined(__AST_DEBUG_MALLOC) 01704 if (!(pool = __ast_calloc(1, alloc_size, file, lineno, func))) { 01705 return -1; 01706 } 01707 #else 01708 if (!(pool = ast_calloc(1, alloc_size))) { 01709 return -1; 01710 } 01711 #endif 01712 01713 pool->prev = *pool_head; 01714 pool->size = alloc_size - sizeof(*pool); 01715 *pool_head = pool; 01716 mgr->last_alloc = NULL; 01717 01718 return 0; 01719 }
| int ast_atomic_fetchadd_int_slow | ( | volatile int * | p, | |
| int | v | |||
| ) |
Definition at line 2011 of file utils.c.
References ast_mutex_lock, ast_mutex_unlock, and fetchadd_m.
02012 { 02013 int ret; 02014 ast_mutex_lock(&fetchadd_m); 02015 ret = *p; 02016 *p += v; 02017 ast_mutex_unlock(&fetchadd_m); 02018 return ret; 02019 }
| int ast_base64decode | ( | unsigned char * | dst, | |
| const char * | src, | |||
| int | max | |||
| ) |
decode BASE64 encoded text
Decode data from base64.
Definition at line 272 of file utils.c.
Referenced by aes_helper(), ast_check_signature(), base64_helper(), osp_validate_token(), sdp_crypto_process(), and sdp_crypto_setup().
00273 { 00274 int cnt = 0; 00275 unsigned int byte = 0; 00276 unsigned int bits = 0; 00277 int incnt = 0; 00278 while(*src && *src != '=' && (cnt < max)) { 00279 /* Shift in 6 bits of input */ 00280 byte <<= 6; 00281 byte |= (b2a[(int)(*src)]) & 0x3f; 00282 bits += 6; 00283 src++; 00284 incnt++; 00285 /* If we have at least 8 bits left over, take that character 00286 off the top */ 00287 if (bits >= 8) { 00288 bits -= 8; 00289 *dst = (byte >> bits) & 0xff; 00290 dst++; 00291 cnt++; 00292 } 00293 } 00294 /* Don't worry about left over bits, they're extra anyway */ 00295 return cnt; 00296 }
| int ast_base64encode | ( | char * | dst, | |
| const unsigned char * | src, | |||
| int | srclen, | |||
| int | max | |||
| ) |
Encode data in base64.
| dst | the destination buffer | |
| src | the source data to be encoded | |
| srclen | the number of bytes present in the source buffer | |
| max | the maximum number of bytes to write into the destination buffer, *including* the terminating NULL character. |
Definition at line 350 of file utils.c.
References ast_base64encode_full().
Referenced by aes_helper(), aji_start_sasl(), ast_sign(), base64_helper(), build_secret(), osp_check_destination(), and sdp_crypto_setup().
00351 { 00352 return ast_base64encode_full(dst, src, srclen, max, 0); 00353 }
| int ast_base64encode_full | ( | char * | dst, | |
| const unsigned char * | src, | |||
| int | srclen, | |||
| int | max, | |||
| int | linebreaks | |||
| ) |
encode text to BASE64 coding
Definition at line 299 of file utils.c.
Referenced by ast_base64encode().
00300 { 00301 int cnt = 0; 00302 int col = 0; 00303 unsigned int byte = 0; 00304 int bits = 0; 00305 int cntin = 0; 00306 /* Reserve space for null byte at end of string */ 00307 max--; 00308 while ((cntin < srclen) && (cnt < max)) { 00309 byte <<= 8; 00310 byte |= *(src++); 00311 bits += 8; 00312 cntin++; 00313 if ((bits == 24) && (cnt + 4 <= max)) { 00314 *dst++ = base64[(byte >> 18) & 0x3f]; 00315 *dst++ = base64[(byte >> 12) & 0x3f]; 00316 *dst++ = base64[(byte >> 6) & 0x3f]; 00317 *dst++ = base64[byte & 0x3f]; 00318 cnt += 4; 00319 col += 4; 00320 bits = 0; 00321 byte = 0; 00322 } 00323 if (linebreaks && (cnt < max) && (col == 64)) { 00324 *dst++ = '\n'; 00325 cnt++; 00326 col = 0; 00327 } 00328 } 00329 if (bits && (cnt + 4 <= max)) { 00330 /* Add one last character for the remaining bits, 00331 padding the rest with 0 */ 00332 byte <<= 24 - bits; 00333 *dst++ = base64[(byte >> 18) & 0x3f]; 00334 *dst++ = base64[(byte >> 12) & 0x3f]; 00335 if (bits == 16) 00336 *dst++ = base64[(byte >> 6) & 0x3f]; 00337 else 00338 *dst++ = '='; 00339 *dst++ = '='; 00340 cnt += 4; 00341 } 00342 if (linebreaks && (cnt < max)) { 00343 *dst++ = '\n'; 00344 cnt++; 00345 } 00346 *dst = '\0'; 00347 return cnt; 00348 }
| int ast_build_string | ( | char ** | buffer, | |
| size_t * | space, | |||
| const char * | fmt, | |||
| ... | ||||
| ) |
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.
| buffer | current position in buffer to place string into (will be updated on return) | |
| space | remaining space in buffer (will be updated on return) | |
| fmt | printf-style format string |
| 0 | on success | |
| non-zero | on failure. |
Definition at line 1474 of file utils.c.
References ast_build_string_va().
Referenced by ast_fax_caps_to_str(), config_odbc(), generate_filenames_string(), handle_speechrecognize(), pp_each_extension_helper(), and pp_each_user_helper().
01475 { 01476 va_list ap; 01477 int result; 01478 01479 va_start(ap, fmt); 01480 result = ast_build_string_va(buffer, space, fmt, ap); 01481 va_end(ap); 01482 01483 return result; 01484 }
| 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.
| buffer | current position in buffer to place string into (will be updated on return) | |
| space | remaining space in buffer (will be updated on return) | |
| fmt | printf-style format string | |
| ap | varargs list of arguments for format |
Definition at line 1455 of file utils.c.
Referenced by ast_build_string().
01456 { 01457 int result; 01458 01459 if (!buffer || !*buffer || !space || !*space) 01460 return -1; 01461 01462 result = vsnprintf(*buffer, *space, fmt, ap); 01463 01464 if (result < 0) 01465 return -1; 01466 else if (result > *space) 01467 result = *space; 01468 01469 *buffer += result; 01470 *space -= result; 01471 return 0; 01472 }
| int ast_careful_fwrite | ( | FILE * | f, | |
| int | fd, | |||
| const char * | s, | |||
| size_t | len, | |||
| int | timeoutms | |||
| ) |
Write data to a file stream with a timeout.
| f | the file stream to write to | |
| fd | the file description to poll on to know when the file stream can be written to without blocking. | |
| s | the buffer to write from | |
| len | the number of bytes to write | |
| timeoutms | The maximum amount of time to block in this function trying to write, specified in milliseconds. |
| 0 | success | |
| -1 | error |
Definition at line 1329 of file utils.c.
References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_wait_for_output(), errno, and LOG_ERROR.
Referenced by send_string().
01330 { 01331 struct timeval start = ast_tvnow(); 01332 int n = 0; 01333 int elapsed = 0; 01334 01335 while (len) { 01336 if (ast_wait_for_output(fd, timeoutms - elapsed)) { 01337 /* poll returned a fatal error, so bail out immediately. */ 01338 return -1; 01339 } 01340 01341 /* Clear any errors from a previous write */ 01342 clearerr(f); 01343 01344 n = fwrite(src, 1, len, f); 01345 01346 if (ferror(f) && errno != EINTR && errno != EAGAIN) { 01347 /* fatal error from fwrite() */ 01348 if (!feof(f)) { 01349 /* Don't spam the logs if it was just that the connection is closed. */ 01350 ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno)); 01351 } 01352 n = -1; 01353 break; 01354 } 01355 01356 /* Update for data already written to the socket */ 01357 len -= n; 01358 src += n; 01359 01360 elapsed = ast_tvdiff_ms(ast_tvnow(), start); 01361 if (elapsed >= timeoutms) { 01362 /* We've taken too long to write 01363 * This is only an error condition if we haven't finished writing. */ 01364 n = len ? -1 : 0; 01365 break; 01366 } 01367 } 01368 01369 while (fflush(f)) { 01370 if (errno == EAGAIN || errno == EINTR) { 01371 continue; 01372 } 01373 if (!feof(f)) { 01374 /* Don't spam the logs if it was just that the connection is closed. */ 01375 ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno)); 01376 } 01377 n = -1; 01378 break; 01379 } 01380 01381 return n < 0 ? -1 : 0; 01382 }
| 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.
Definition at line 1288 of file utils.c.
References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_wait_for_output(), errno, and LOG_ERROR.
Referenced by ast_agi_send(), and ast_cli().
01289 { 01290 struct timeval start = ast_tvnow(); 01291 int res = 0; 01292 int elapsed = 0; 01293 01294 while (len) { 01295 if (ast_wait_for_output(fd, timeoutms - elapsed)) { 01296 return -1; 01297 } 01298 01299 res = write(fd, s, len); 01300 01301 if (res < 0 && errno != EAGAIN && errno != EINTR) { 01302 /* fatal error from write() */ 01303 ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno)); 01304 return -1; 01305 } 01306 01307 if (res < 0) { 01308 /* It was an acceptable error */ 01309 res = 0; 01310 } 01311 01312 /* Update how much data we have left to write */ 01313 len -= res; 01314 s += res; 01315 res = 0; 01316 01317 elapsed = ast_tvdiff_ms(ast_tvnow(), start); 01318 if (elapsed >= timeoutms) { 01319 /* We've taken too long to write 01320 * This is only an error condition if we haven't finished writing. */ 01321 res = len ? -1 : 0; 01322 break; 01323 } 01324 } 01325 01326 return res; 01327 }
| void ast_do_crash | ( | void | ) |
Force a crash if DO_CRASH is defined.
Definition at line 2297 of file utils.c.
Referenced by my_do_crash().
| void ast_enable_packet_fragmentation | ( | int | sock | ) |
Disable PMTU discovery on a socket.
| sock | The socket to manipulate |
On Linux, UDP sockets default to sending packets with the Dont Fragment (DF) bit set. This is supposedly done to allow the application to do PMTU discovery, but Asterisk does not do this.
Because of this, UDP packets sent by Asterisk that are larger than the MTU of any hop in the path will be lost. This function can be called on a socket to ensure that the DF bit will not be set.
Definition at line 2074 of file utils.c.
References ast_log(), and LOG_WARNING.
Referenced by ast_netsock_bindaddr(), and reload_config().
02075 { 02076 #if defined(HAVE_IP_MTU_DISCOVER) 02077 int val = IP_PMTUDISC_DONT; 02078 02079 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) 02080 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n"); 02081 #endif /* HAVE_IP_MTU_DISCOVER */ 02082 }
| char* ast_escape_quoted | ( | const char * | string, | |
| char * | outbuf, | |||
| int | buflen | |||
| ) |
escapes characters specified for quoted portions of sip messages
Escape characters found in a quoted string.
Definition at line 424 of file utils.c.
Referenced by initreqprep().
00425 { 00426 const char *ptr = string; 00427 char *out = outbuf; 00428 char *allow = "\t\v !"; /* allow LWS (minus \r and \n) and "!" */ 00429 00430 while (*ptr && out - outbuf < buflen - 1) { 00431 if (!(strchr(allow, *ptr)) 00432 && !(*ptr >= '#' && *ptr <= '[') /* %x23 - %x5b */ 00433 && !(*ptr >= ']' && *ptr <= '~') /* %x5d - %x7e */ 00434 && !((unsigned char) *ptr > 0x7f)) { /* UTF8-nonascii */ 00435 00436 if (out - outbuf >= buflen - 2) { 00437 break; 00438 } 00439 out += sprintf(out, "\\%c", (unsigned char) *ptr); 00440 } else { 00441 *out = *ptr; 00442 out++; 00443 } 00444 ptr++; 00445 } 00446 00447 if (buflen) { 00448 *out = '\0'; 00449 } 00450 00451 return outbuf; 00452 }
| 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".
| 0 | if val is a NULL pointer. | |
| -1 | if "true". | |
| 0 | otherwise. |
Definition at line 1503 of file utils.c.
References ast_strlen_zero().
Referenced by __ast_udptl_reload(), acf_faxopt_write(), acf_transaction_write(), actual_load_config(), aji_create_client(), aji_load_config(), aoc_cli_debug_enable(), build_peer(), build_user(), dahdi_set_dnd(), find_realtime(), func_channel_write_real(), handle_common_options(), handle_memory_atexit_list(), handle_memory_atexit_summary(), init_acf_query(), load_config(), load_odbc_config(), manager_mute_mixmonitor(), parse_empty_options(), reload_config(), rtp_reload(), run_agi(), set_config(), set_insecure_flags(), sla_build_trunk(), and strings_to_mask().
01504 { 01505 if (ast_strlen_zero(s)) 01506 return 0; 01507 01508 /* Determine if this is a false value */ 01509 if (!strcasecmp(s, "no") || 01510 !strcasecmp(s, "false") || 01511 !strcasecmp(s, "n") || 01512 !strcasecmp(s, "f") || 01513 !strcasecmp(s, "0") || 01514 !strcasecmp(s, "off")) 01515 return -1; 01516 01517 return 0; 01518 }
| int ast_get_time_t | ( | const char * | src, | |
| time_t * | dst, | |||
| time_t | _default, | |||
| int * | consumed | |||
| ) |
get values from config variables.
Definition at line 2051 of file utils.c.
References ast_strlen_zero().
Referenced by build_peer(), cache_lookup_internal(), handle_saydatetime(), load_password(), play_message_datetime(), process_clearcache(), realtime_peer(), and sayunixtime_exec().
02052 { 02053 long t; 02054 int scanned; 02055 02056 if (dst == NULL) 02057 return -1; 02058 02059 *dst = _default; 02060 02061 if (ast_strlen_zero(src)) 02062 return -1; 02063 02064 /* only integer at the moment, but one day we could accept more formats */ 02065 if (sscanf(src, "%30ld%n", &t, &scanned) == 1) { 02066 *dst = t; 02067 if (consumed) 02068 *consumed = scanned; 02069 return 0; 02070 } else 02071 return -1; 02072 }
| int ast_get_timeval | ( | const char * | src, | |
| struct timeval * | dst, | |||
| struct timeval | _default, | |||
| int * | consumed | |||
| ) |
get values from config variables.
Definition at line 2024 of file utils.c.
References ast_strlen_zero().
Referenced by acf_strftime().
02025 { 02026 long double dtv = 0.0; 02027 int scanned; 02028 02029 if (dst == NULL) 02030 return -1; 02031 02032 *dst = _default; 02033 02034 if (ast_strlen_zero(src)) 02035 return -1; 02036 02037 /* only integer at the moment, but one day we could accept more formats */ 02038 if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) { 02039 dst->tv_sec = dtv; 02040 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0; 02041 if (consumed) 02042 *consumed = scanned; 02043 return 0; 02044 } else 02045 return -1; 02046 }
| struct hostent* ast_gethostbyname | ( | const char * | host, | |
| struct ast_hostent * | hp | |||
| ) | [read] |
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 188 of file utils.c.
References ast_hostent::buf, and ast_hostent::hp.
Referenced by __ast_http_load(), app_exec(), ast_parse_arg(), build_peer(), config_load(), config_parse_variables(), create_addr(), festival_exec(), gtalk_load_config(), gtalk_update_stun(), iax_template_parse(), jingle_load_config(), jingle_update_stun(), launch_netscript(), process_sdp(), realtime_peer(), realtime_user(), reload_config(), and set_config().
00189 { 00190 int res; 00191 int herrno; 00192 int dots = 0; 00193 const char *s; 00194 struct hostent *result = NULL; 00195 /* Although it is perfectly legitimate to lookup a pure integer, for 00196 the sake of the sanity of people who like to name their peers as 00197 integers, we break with tradition and refuse to look up a 00198 pure integer */ 00199 s = host; 00200 res = 0; 00201 while (s && *s) { 00202 if (*s == '.') 00203 dots++; 00204 else if (!isdigit(*s)) 00205 break; 00206 s++; 00207 } 00208 if (!s || !*s) { 00209 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */ 00210 if (dots != 3) 00211 return NULL; 00212 memset(hp, 0, sizeof(struct ast_hostent)); 00213 hp->hp.h_addrtype = AF_INET; 00214 hp->hp.h_addr_list = (void *) hp->buf; 00215 hp->hp.h_addr = hp->buf + sizeof(void *); 00216 /* For AF_INET, this will always be 4 */ 00217 hp->hp.h_length = 4; 00218 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0) 00219 return &hp->hp; 00220 return NULL; 00221 00222 } 00223 #ifdef HAVE_GETHOSTBYNAME_R_5 00224 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno); 00225 00226 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0]) 00227 return NULL; 00228 #else 00229 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno); 00230 00231 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0]) 00232 return NULL; 00233 #endif 00234 return &hp->hp; 00235 }
| 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 535 of file utils.c.
References ast_threadstorage_get(), and inet_ntoa_buf.
Referenced by __attempt_transmit(), __find_callno(), __iax2_show_peers(), _skinny_show_device(), _skinny_show_devices(), acf_channel_read(), action_login(), add_ipv4_ie(), add_sdp(), ast_apply_ha(), ast_netsock_bindaddr(), ast_parse_arg(), auth_http_callback(), authenticate(), calltoken_required(), check_access(), config_load(), create_client(), data_get_xml_add_child(), data_result_manager_output(), data_result_print_cli_node(), do_message(), dump_addr(), dump_ipaddr(), dundi_rexmit(), dundi_show_peer(), dundi_show_peers(), dundi_show_trans(), dundi_showframe(), dundi_xmit(), external_rtp_create(), find_command(), find_peer(), find_subchannel_and_lock(), find_tpeer(), function_iaxpeer(), generic_http_callback(), get_input(), gtalk_update_externip(), gtalk_update_stun(), handle_call_token(), handle_cli_iax2_set_debug(), handle_cli_iax2_show_callno_limits(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_peer(), handle_cli_iax2_show_registry(), handle_command_response(), handle_error(), handle_mgcp_show_endpoints(), handle_open_receive_channel_ack_message(), handle_request(), handle_show_http(), handle_showmanconn(), handle_skinny_show_settings(), iax2_ack_registry(), iax2_prov_app(), iax2_trunk_queue(), iax_server(), iax_showframe(), jingle_create_candidates(), load_module(), manager_iax2_show_peer_list(), manager_iax2_show_registry(), mgcpsock_read(), oh323_addrcmp_str(), oh323_call(), oh323_set_rtp_peer(), parsing(), peercnt_add(), peercnt_modify(), peercnt_remove(), peers_data_provider_get(), phoneprov_callback(), process_request(), process_sdp(), purge_sessions(), raw_hangup(), realtime_peer(), realtime_user(), register_verify(), registry_rerequest(), reload_config(), resend_response(), sched_delay_remove(), score_address(), send_packet(), send_raw_client(), send_request(), send_response(), send_trunk(), session_do(), set_config(), set_peercnt_limit(), setup_incoming_call(), show_main_page(), skinny_session(), skinny_set_rtp_peer(), socket_process(), socket_process_meta(), start_rtp(), stun_monitor_request(), timing_read(), unistim_info(), unistimsock_read(), and update_registry().
00536 { 00537 char *buf; 00538 00539 if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN))) 00540 return ""; 00541 00542 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN); 00543 }
| void ast_join | ( | char * | s, | |
| size_t | len, | |||
| const char *const | w[] | |||
| ) |
Definition at line 1643 of file utils.c.
Referenced by __ast_cli_generator(), ast_agi_register(), ast_agi_unregister(), ast_cli_command_full(), cli_console_sendtext(), console_sendtext(), find_best(), handle_cli_agi_show(), handle_cli_check_permissions(), handle_help(), help1(), help_workhorse(), set_full_cmd(), and write_htmldump().
01644 { 01645 int x, ofs = 0; 01646 const char *src; 01647 01648 /* Join words into a string */ 01649 if (!s) 01650 return; 01651 for (x = 0; ofs < len && w[x]; x++) { 01652 if (x > 0) 01653 s[ofs++] = ' '; 01654 for (src = w[x]; *src && ofs < len; src++) 01655 s[ofs++] = *src; 01656 } 01657 if (ofs == len) 01658 ofs--; 01659 s[ofs] = '\0'; 01660 }
| 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 238 of file utils.c.
References MD5Final(), MD5Init(), and MD5Update().
Referenced by __init_manager(), auth_exec(), auth_http_callback(), build_reply_digest(), check_auth(), and md5().
00239 { 00240 struct MD5Context md5; 00241 unsigned char digest[16]; 00242 char *ptr; 00243 int x; 00244 00245 MD5Init(&md5); 00246 MD5Update(&md5, (const unsigned char *) input, strlen(input)); 00247 MD5Final(digest, &md5); 00248 ptr = output; 00249 for (x = 0; x < 16; x++) 00250 ptr += sprintf(ptr, "%2.2x", digest[x]); 00251 }
| int ast_mkdir | ( | const char * | path, | |
| int | mode | |||
| ) |
Recursively create directory path.
| path | The directory path to create | |
| mode | The permissions with which to try to create the directory |
Creates a directory path, creating parent directories as needed.
Definition at line 2084 of file utils.c.
References ast_alloca, ast_strdupa, errno, and len().
Referenced by ast_monitor_change_fname(), ast_monitor_start(), conf_run(), create_dirpath(), dictate_exec(), filename_parse(), init_logger(), load_module(), mixmonitor_exec(), record_exec(), reload_logger(), remove_from_queue(), setup_privacy_args(), sms_nextoutgoing(), sms_writefile(), testclient_exec(), testserver_exec(), and write_history().
02085 { 02086 char *ptr; 02087 int len = strlen(path), count = 0, x, piececount = 0; 02088 char *tmp = ast_strdupa(path); 02089 char **pieces; 02090 char *fullpath = ast_alloca(len + 1); 02091 int res = 0; 02092 02093 for (ptr = tmp; *ptr; ptr++) { 02094 if (*ptr == '/') 02095 count++; 02096 } 02097 02098 /* Count the components to the directory path */ 02099 pieces = ast_alloca(count * sizeof(*pieces)); 02100 for (ptr = tmp; *ptr; ptr++) { 02101 if (*ptr == '/') { 02102 *ptr = '\0'; 02103 pieces[piececount++] = ptr + 1; 02104 } 02105 } 02106 02107 *fullpath = '\0'; 02108 for (x = 0; x < piececount; x++) { 02109 /* This looks funky, but the buffer is always ideally-sized, so it's fine. */ 02110 strcat(fullpath, "/"); 02111 strcat(fullpath, pieces[x]); 02112 res = mkdir(fullpath, mode); 02113 if (res && errno != EEXIST) 02114 return errno; 02115 } 02116 return 0; 02117 }
| int ast_parse_digest | ( | const char * | digest, | |
| struct ast_http_digest * | d, | |||
| int | request, | |||
| int | pedantic | |||
| ) |
Parse digest authorization header.
Definition at line 2149 of file 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(), ast_http_digest::cnonce, ast_http_digest::domain, LOG_WARNING, ast_http_digest::nc, ast_http_digest::nonce, ast_http_digest::opaque, ast_http_digest::qop, ast_http_digest::realm, ast_http_digest::response, ast_http_digest::uri, and ast_http_digest::username.
Referenced by auth_http_callback().
02149 { 02150 char *c; 02151 struct ast_str *str = ast_str_create(16); 02152 02153 /* table of recognised keywords, and places where they should be copied */ 02154 const struct x { 02155 const char *key; 02156 const ast_string_field *field; 02157 } *i, keys[] = { 02158 { "username=", &d->username }, 02159 { "realm=", &d->realm }, 02160 { "nonce=", &d->nonce }, 02161 { "uri=", &d->uri }, 02162 { "domain=", &d->domain }, 02163 { "response=", &d->response }, 02164 { "cnonce=", &d->cnonce }, 02165 { "opaque=", &d->opaque }, 02166 /* Special cases that cannot be directly copied */ 02167 { "algorithm=", NULL }, 02168 { "qop=", NULL }, 02169 { "nc=", NULL }, 02170 { NULL, 0 }, 02171 }; 02172 02173 if (ast_strlen_zero(digest) || !d || !str) { 02174 ast_free(str); 02175 return -1; 02176 } 02177 02178 ast_str_set(&str, 0, "%s", digest); 02179 02180 c = ast_skip_blanks(ast_str_buffer(str)); 02181 02182 if (strncasecmp(c, "Digest ", strlen("Digest "))) { 02183 ast_log(LOG_WARNING, "Missing Digest.\n"); 02184 ast_free(str); 02185 return -1; 02186 } 02187 c += strlen("Digest "); 02188 02189 /* lookup for keys/value pair */ 02190 while (c && *c && *(c = ast_skip_blanks(c))) { 02191 /* find key */ 02192 for (i = keys; i->key != NULL; i++) { 02193 char *src, *separator; 02194 int unescape = 0; 02195 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 02196 continue; 02197 } 02198 02199 /* Found. Skip keyword, take text in quotes or up to the separator. */ 02200 c += strlen(i->key); 02201 if (*c == '"') { 02202 src = ++c; 02203 separator = "\""; 02204 unescape = 1; 02205 } else { 02206 src = c; 02207 separator = ","; 02208 } 02209 strsep(&c, separator); /* clear separator and move ptr */ 02210 if (unescape) { 02211 ast_unescape_c(src); 02212 } 02213 if (i->field) { 02214 ast_string_field_ptr_set(d, i->field, src); 02215 } else { 02216 /* Special cases that require additional procesing */ 02217 if (!strcasecmp(i->key, "algorithm=")) { 02218 if (strcasecmp(src, "MD5")) { 02219 ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src); 02220 ast_free(str); 02221 return -1; 02222 } 02223 } else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) { 02224 d->qop = 1; 02225 } else if (!strcasecmp(i->key, "nc=")) { 02226 unsigned long u; 02227 if (sscanf(src, "%30lx", &u) != 1) { 02228 ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src); 02229 ast_free(str); 02230 return -1; 02231 } 02232 ast_string_field_set(d, nc, src); 02233 } 02234 } 02235 break; 02236 } 02237 if (i->key == NULL) { /* not found, try ',' */ 02238 strsep(&c, ","); 02239 } 02240 } 02241 ast_free(str); 02242 02243 /* Digest checkout */ 02244 if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) { 02245 /* "realm" and "nonce" MUST be always exist */ 02246 return -1; 02247 } 02248 02249 if (!request) { 02250 /* Additional check for Digest response */ 02251 if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) { 02252 return -1; 02253 } 02254 02255 if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) { 02256 return -1; 02257 } 02258 } 02259 02260 return 0; 02261 }
| char* ast_process_quotes_and_slashes | ( | char * | start, | |
| char | find, | |||
| char | replace_with | |||
| ) |
Process a string to find and replace characters.
| start | The string to analyze | |
| find | The character to find | |
| replace_with | The character that will replace the one we are looking for |
Definition at line 1617 of file utils.c.
01618 { 01619 char *dataPut = start; 01620 int inEscape = 0; 01621 int inQuotes = 0; 01622 01623 for (; *start; start++) { 01624 if (inEscape) { 01625 *dataPut++ = *start; /* Always goes verbatim */ 01626 inEscape = 0; 01627 } else { 01628 if (*start == '\\') { 01629 inEscape = 1; /* Do not copy \ into the data */ 01630 } else if (*start == '\'') { 01631 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */ 01632 } else { 01633 /* Replace , with |, unless in quotes */ 01634 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start); 01635 } 01636 } 01637 } 01638 if (start != dataPut) 01639 *dataPut = 0; 01640 return dataPut; 01641 }
| 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 1201 of file utils.c.
References ast_alloca, ast_log(), ast_pthread_create_stack(), errno, LOG_WARNING, and thr_arg::start_routine.
01204 { 01205 unsigned char attr_destroy = 0; 01206 int res; 01207 01208 if (!attr) { 01209 attr = ast_alloca(sizeof(*attr)); 01210 pthread_attr_init(attr); 01211 attr_destroy = 1; 01212 } 01213 01214 if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED))) 01215 ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno)); 01216 01217 res = ast_pthread_create_stack(thread, attr, start_routine, data, 01218 stacksize, file, caller, line, start_fn); 01219 01220 if (attr_destroy) 01221 pthread_attr_destroy(attr); 01222 01223 return res; 01224 }
| 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 1153 of file utils.c.
References ast_alloca, ast_asprintf, ast_log(), ast_malloc, AST_STACKSIZE, thr_arg::data, dummy_start(), errno, LOG_WARNING, thr_arg::name, pthread_create, and thr_arg::start_routine.
Referenced by ast_pthread_create_detached_stack().
01156 { 01157 #if !defined(LOW_MEMORY) 01158 struct thr_arg *a; 01159 #endif 01160 01161 if (!attr) { 01162 attr = ast_alloca(sizeof(*attr)); 01163 pthread_attr_init(attr); 01164 } 01165 01166 #ifdef __linux__ 01167 /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED, 01168 which is kind of useless. Change this here to 01169 PTHREAD_INHERIT_SCHED; that way the -p option to set realtime 01170 priority will propagate down to new threads by default. 01171 This does mean that callers cannot set a different priority using 01172 PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set 01173 the priority afterwards with pthread_setschedparam(). */ 01174 if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED))) 01175 ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno)); 01176 #endif 01177 01178 if (!stacksize) 01179 stacksize = AST_STACKSIZE; 01180 01181 if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE))) 01182 ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno)); 01183 01184 #if !defined(LOW_MEMORY) 01185 if ((a = ast_malloc(sizeof(*a)))) { 01186 a->start_routine = start_routine; 01187 a->data = data; 01188 start_routine = dummy_start; 01189 if (ast_asprintf(&a->name, "%-20s started at [%5d] %s %s()", 01190 start_fn, line, file, caller) < 0) { 01191 a->name = NULL; 01192 } 01193 data = a; 01194 } 01195 #endif /* !LOW_MEMORY */ 01196 01197 return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */ 01198 }
| long int ast_random | ( | void | ) |
Definition at line 1593 of file utils.c.
References ast_mutex_lock, ast_mutex_unlock, and randomlock.
Referenced by acf_rand_exec(), action_challenge(), add_sdp(), agent_new(), agi_handle_command(), ast_lock_path_lockfile(), ast_moh_files_next(), ast_rtp_change_source(), ast_rtp_new(), ast_udptl_new_with_bindaddr(), auth_http_callback(), authenticate_request(), build_gateway(), build_iv(), build_localtag_registry(), build_rand_pad(), build_reply_digest(), calc_metric(), calc_rxstamp(), caldav_write_event(), callno_hash(), create_channel_name(), generate_exchange_uuid(), generate_random_string(), generic_http_callback(), get_trans_id(), gtalk_alloc(), gtalk_create_candidates(), gtalk_new(), handle_incoming(), handle_response_invite(), iax2_key_rotate(), iax2_start_transfer(), jingle_alloc(), jingle_create_candidates(), jingle_new(), load_module(), make_email_file(), make_our_tag(), moh_files_alloc(), multicast_rtp_new(), ogg_vorbis_rewrite(), osp_create_uuid(), page_exec(), park_space_reserve(), process_weights(), reg_source_db(), registry_authrequest(), reqprep(), say_periodic_announcement(), sendmail(), set_nonce_randdata(), sip_alloc(), socket_read(), start_rtp(), stun_req_id(), transmit_invite(), transmit_register(), transmit_response_using_temp(), try_calling(), and try_firmware().
01594 { 01595 long int res; 01596 #ifdef HAVE_DEV_URANDOM 01597 if (dev_urandom_fd >= 0) { 01598 int read_res = read(dev_urandom_fd, &res, sizeof(res)); 01599 if (read_res > 0) { 01600 long int rm = RAND_MAX; 01601 res = res < 0 ? ~res : res; 01602 rm++; 01603 return res % rm; 01604 } 01605 } 01606 #endif 01607 #ifdef linux 01608 res = random(); 01609 #else 01610 ast_mutex_lock(&randomlock); 01611 res = random(); 01612 ast_mutex_unlock(&randomlock); 01613 #endif 01614 return res; 01615 }
| 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.
| start | When timing started being calculated | |
| max_ms | The maximum number of milliseconds to wait from start. May be negative. |
Definition at line 1568 of file utils.c.
References ast_tvdiff_ms(), and ast_tvnow().
Referenced by __analog_ss_thread(), __ast_answer(), __ast_request_and_dial(), agent_ack_sleep(), analog_ss_thread(), ast_recvtext(), ast_safe_sleep_conditional(), ast_waitfordigit_full(), async_wait(), dahdi_bridge(), disable_t38(), find_cache(), generic_fax_exec(), local_bridge_loop(), receivefax_t38_init(), record_exec(), remote_bridge_loop(), sendfax_t38_init(), wait_for_answer(), and waitforring_exec().
01569 { 01570 int ms; 01571 01572 if (max_ms < 0) { 01573 ms = max_ms; 01574 } else { 01575 ms = max_ms - ast_tvdiff_ms(ast_tvnow(), start); 01576 if (ms < 0) { 01577 ms = 0; 01578 } 01579 } 01580 01581 return ms; 01582 }
| 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 254 of file utils.c.
References SHA1Input(), SHA1Reset(), and SHA1Result().
Referenced by aji_act_hook(), handle_call_token(), jabber_make_auth(), and sha1().
00255 { 00256 struct SHA1Context sha; 00257 char *ptr; 00258 int x; 00259 uint8_t Message_Digest[20]; 00260 00261 SHA1Reset(&sha); 00262 00263 SHA1Input(&sha, (const unsigned char *) input, strlen(input)); 00264 00265 SHA1Result(&sha, Message_Digest); 00266 ptr = output; 00267 for (x = 0; x < 20; x++) 00268 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]); 00269 }
| char* ast_strip_quoted | ( | char * | s, | |
| const char * | beg_quotes, | |||
| const char * | end_quotes | |||
| ) |
Strip leading/trailing whitespace and quotes from a string.
| s | The string to be stripped (will be modified). | |
| beg_quotes | The list of possible beginning quote characters. | |
| end_quotes | The list of matching ending quote characters. |
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 1384 of file utils.c.
References ast_strip().
Referenced by ast_register_file_version(), get_rdnis(), iftime(), load_values_config(), parse_allowed_methods(), parse_cookies(), parse_dial_string(), and sip_parse_register_line().
01385 { 01386 char *e; 01387 char *q; 01388 01389 s = ast_strip(s); 01390 if ((q = strchr(beg_quotes, *s)) && *q != '\0') { 01391 e = s + strlen(s) - 1; 01392 if (*e == *(end_quotes + (q - beg_quotes))) { 01393 s++; 01394 *e = '\0'; 01395 } 01396 } 01397 01398 return s; 01399 }
| 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".
| 0 | if val is a NULL pointer. | |
| -1 | if "true". | |
| 0 | otherwise. |
Definition at line 1486 of file utils.c.
References ast_strlen_zero().
Referenced by __ast_http_load(), __ast_udptl_reload(), __init_manager(), _parse(), acf_curlopt_write(), acf_faxopt_write(), acf_transaction_write(), action_agent_logoff(), action_bridge(), action_originate(), action_updateconfig(), actual_load_config(), aji_create_client(), aji_load_config(), aoc_cli_debug_enable(), apply_general_options(), apply_option(), apply_outgoing(), ast_bridge_timelimit(), ast_jb_read_conf(), AST_LIST_HEAD_NOLOCK(), ast_plc_reload(), ast_readconfig(), ast_tls_read_conf(), autopause2int(), build_device(), build_gateway(), build_peer(), build_user(), config_parse_variables(), dahdi_set_dnd(), data_search_cmp_bool(), do_reload(), festival_exec(), func_channel_write_real(), func_inheritance_write(), func_mute_write(), get_encrypt_methods(), gtalk_load_config(), handle_common_options(), handle_logger_set_level(), handle_memory_atexit_list(), handle_t38_options(), init_logger_chain(), jingle_load_config(), load_config(), load_config_meetme(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), local_ast_moh_start(), login_exec(), manager_add_queue_member(), manager_mutestream(), manager_pause_queue_member(), message_template_build(), misdn_answer(), odbc_load_module(), osp_load(), osplookup_exec(), parkinglot_config_read(), parse_config(), parse_empty_options(), pbx_load_config(), pbx_load_users(), process_config(), process_dahdi(), process_echocancel(), queue_set_global_params(), queue_set_param(), read_agent_config(), realtime_directory(), reload_config(), rtp_reload(), run_startup_commands(), search_directory(), set_active(), set_config(), sla_load_config(), smdi_load(), speex_write(), stackpeek_read(), start_monitor_action(), strings_to_mask(), tds_load_module(), update_common_options(), xmldoc_get_syntax_cmd(), xmldoc_get_syntax_fun(), and xmldoc_get_syntax_manager().
01487 { 01488 if (ast_strlen_zero(s)) 01489 return 0; 01490 01491 /* Determine if this is a true value */ 01492 if (!strcasecmp(s, "yes") || 01493 !strcasecmp(s, "true") || 01494 !strcasecmp(s, "y") || 01495 !strcasecmp(s, "t") || 01496 !strcasecmp(s, "1") || 01497 !strcasecmp(s, "on")) 01498 return -1; 01499 01500 return 0; 01501 }
| struct timeval ast_tvadd | ( | struct timeval | a, | |
| struct timeval | b | |||
| ) | [read] |
Returns the sum of two timevals a + b.
Definition at line 1540 of file utils.c.
References ONE_MILLION, and tvfix().
Referenced by __get_from_jb(), acf_jabberreceive_read(), agent_hangup(), ast_audiohook_trigger_wait(), ast_channel_bridge(), ast_channel_cmpwhentohangup_tv(), ast_channel_setwhentohangup_tv(), ast_generic_bridge(), ast_poll2(), ast_rtp_dtmf_begin(), ast_rtp_dtmf_end_with_duration(), ast_rtp_sendcng(), ast_sched_runq(), ast_smoother_read(), ast_translate(), calc_rxstamp(), calc_timestamp(), cli_tps_ping(), conf_run(), dial_exec_full(), do_cdr(), do_timing(), iax2_process_thread(), jb_get_and_deliver(), mb_poll_thread(), monmp3thread(), mp3_exec(), mwi_monitor_handler(), NBScat_exec(), sched_run(), sched_settime(), schedule_delivery(), sla_process_timers(), smdi_message_wait(), and timeout_write().
01541 { 01542 /* consistency checks to guarantee usec in 0..999999 */ 01543 a = tvfix(a); 01544 b = tvfix(b); 01545 a.tv_sec += b.tv_sec; 01546 a.tv_usec += b.tv_usec; 01547 if (a.tv_usec >= ONE_MILLION) { 01548 a.tv_sec++; 01549 a.tv_usec -= ONE_MILLION; 01550 } 01551 return a; 01552 }
| struct timeval ast_tvsub | ( | struct timeval | a, | |
| struct timeval | b | |||
| ) | [read] |
Returns the difference of two timevals a - b.
Definition at line 1554 of file utils.c.
References ONE_MILLION, and tvfix().
Referenced by ast_channel_bridge(), ast_poll2(), ast_sched_dump(), ast_translate(), ast_waitfor_nandfds(), calc_rxstamp(), calc_timestamp(), cli_tps_ping(), conf_run(), debug_check_frame_for_silence(), handle_showcalls(), and handle_showuptime().
01555 { 01556 /* consistency checks to guarantee usec in 0..999999 */ 01557 a = tvfix(a); 01558 b = tvfix(b); 01559 a.tv_sec -= b.tv_sec; 01560 a.tv_usec -= b.tv_usec; 01561 if (a.tv_usec < 0) { 01562 a.tv_sec-- ; 01563 a.tv_usec += ONE_MILLION; 01564 } 01565 return a; 01566 }
| 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).
Definition at line 1420 of file utils.c.
Referenced by ast_parse_digest().
01421 { 01422 char c, *ret, *dst; 01423 01424 if (src == NULL) 01425 return NULL; 01426 for (ret = dst = src; (c = *src++); *dst++ = c ) { 01427 if (c != '\\') 01428 continue; /* copy char at the end of the loop */ 01429 switch ((c = *src++)) { 01430 case '\0': /* special, trailing '\' */ 01431 c = '\\'; 01432 break; 01433 case 'b': /* backspace */ 01434 c = '\b'; 01435 break; 01436 case 'f': /* form feed */ 01437 c = '\f'; 01438 break; 01439 case 'n': 01440 c = '\n'; 01441 break; 01442 case 'r': 01443 c = '\r'; 01444 break; 01445 case 't': 01446 c = '\t'; 01447 break; 01448 } 01449 /* default, use the char literally */ 01450 } 01451 *dst = '\0'; 01452 return ret; 01453 }
| char* ast_unescape_semicolon | ( | char * | s | ) |
Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).
Definition at line 1401 of file utils.c.
Referenced by sip_cli_notify().
| void ast_uri_decode | ( | char * | s | ) |
ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)
Decode URI, URN, URL (overwrite string).
Definition at line 455 of file utils.c.
Referenced by acf_curl_helper(), config_curl(), get_destination(), get_name_and_number(), get_refer_info(), handle_request_invite(), http_decode(), parse_moved_contact(), realtime_curl(), realtime_multi_curl(), sip_new(), sip_uri_cmp(), and uridecode().
00456 { 00457 char *o; 00458 unsigned int tmp; 00459 00460 for (o = s; *s; s++, o++) { 00461 if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) { 00462 /* have '%', two chars and correct parsing */ 00463 *o = tmp; 00464 s += 2; /* Will be incremented once more when we break out */ 00465 } else /* all other cases, just copy */ 00466 *o = *s; 00467 } 00468 *o = '\0'; 00469 }
| char* ast_uri_encode | ( | const char * | string, | |
| char * | outbuf, | |||
| int | buflen, | |||
| int | do_special_char | |||
| ) |
Turn text string to URI-encoded XX version.
Definition at line 391 of file utils.c.
Referenced by add_rpid(), build_contact(), config_curl(), destroy_curl(), initreqprep(), launch_asyncagi(), realtime_curl(), realtime_multi_curl(), require_curl(), store_curl(), update2_curl(), update_curl(), and uriencode().
00392 { 00393 const char *ptr = string; /* Start with the string */ 00394 char *out = outbuf; 00395 const char *mark = "-_.!~*'()"; /* no encode set, RFC 2396 section 2.3, RFC 3261 sec 25 */ 00396 00397 while (*ptr && out - outbuf < buflen - 1) { 00398 if ((const signed char) *ptr < 32 || *ptr == 0x7f || *ptr == '%' || 00399 (do_special_char && 00400 !(*ptr >= '0' && *ptr <= '9') && /* num */ 00401 !(*ptr >= 'A' && *ptr <= 'Z') && /* ALPHA */ 00402 !(*ptr >= 'a' && *ptr <= 'z') && /* alpha */ 00403 !strchr(mark, *ptr))) { /* mark set */ 00404 if (out - outbuf >= buflen - 3) { 00405 break; 00406 } 00407 00408 out += sprintf(out, "%%%02X", (unsigned char) *ptr); 00409 } else { 00410 *out = *ptr; /* Continue copying the string */ 00411 out++; 00412 } 00413 ptr++; 00414 } 00415 00416 if (buflen) { 00417 *out = '\0'; 00418 } 00419 00420 return outbuf; 00421 }
| int ast_utils_init | ( | void | ) |
Definition at line 2126 of file utils.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_register_atexit(), and base64_init().
Referenced by main().
02127 { 02128 #ifdef HAVE_DEV_URANDOM 02129 dev_urandom_fd = open("/dev/urandom", O_RDONLY); 02130 #endif 02131 base64_init(); 02132 #ifdef DEBUG_THREADS 02133 #if !defined(LOW_MEMORY) 02134 ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli)); 02135 ast_register_atexit(utils_shutdown); 02136 #endif 02137 #endif 02138 return 0; 02139 }
| char* ast_utils_which | ( | const char * | binary, | |
| char * | fullpath, | |||
| size_t | fullpath_size | |||
| ) |
Resolve a binary to a full pathname.
| binary | Name of the executable to resolve | |
| fullpath | Buffer to hold the complete pathname | |
| fullpath_size | Size of fullpath |
| NULL | binary was not found or the environment variable PATH is not set |
Definition at line 2279 of file utils.c.
References ast_strdupa.
Referenced by ast_bt_get_symbols().
02280 { 02281 const char *envPATH = getenv("PATH"); 02282 char *tpath, *path; 02283 struct stat unused; 02284 if (!envPATH) { 02285 return NULL; 02286 } 02287 tpath = ast_strdupa(envPATH); 02288 while ((path = strsep(&tpath, ":"))) { 02289 snprintf(fullpath, fullpath_size, "%s/%s", path, binary); 02290 if (!stat(fullpath, &unused)) { 02291 return fullpath; 02292 } 02293 } 02294 return NULL; 02295 }
| int ast_wait_for_input | ( | int | fd, | |
| int | ms | |||
| ) |
Definition at line 1226 of file utils.c.
References ast_poll.
Referenced by action_waitevent(), ast_tcptls_server_root(), dahdi_test_timer(), get_input(), moh_class_destructor(), sip_tcp_read(), and sip_tls_read().
01227 { 01228 struct pollfd pfd[1]; 01229 memset(pfd, 0, sizeof(pfd)); 01230 pfd[0].fd = fd; 01231 pfd[0].events = POLLIN|POLLPRI; 01232 return ast_poll(pfd, 1, ms); 01233 }
| static int ast_wait_for_output | ( | int | fd, | |
| int | timeoutms | |||
| ) | [static] |
Definition at line 1235 of file utils.c.
References ast_debug, ast_log(), ast_poll, ast_tvdiff_ms(), ast_tvnow(), errno, and LOG_ERROR.
Referenced by ast_careful_fwrite(), and ast_carefulwrite().
01236 { 01237 struct pollfd pfd = { 01238 .fd = fd, 01239 .events = POLLOUT, 01240 }; 01241 int res; 01242 struct timeval start = ast_tvnow(); 01243 int elapsed = 0; 01244 01245 /* poll() until the fd is writable without blocking */ 01246 while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) { 01247 if (res == 0) { 01248 /* timed out. */ 01249 #ifndef STANDALONE 01250 ast_debug(1, "Timed out trying to write\n"); 01251 #endif 01252 return -1; 01253 } else if (res == -1) { 01254 /* poll() returned an error, check to see if it was fatal */ 01255 01256 if (errno == EINTR || errno == EAGAIN) { 01257 elapsed = ast_tvdiff_ms(ast_tvnow(), start); 01258 if (elapsed >= timeoutms) { 01259 return -1; 01260 } 01261 /* This was an acceptable error, go back into poll() */ 01262 continue; 01263 } 01264 01265 /* Fatal error, bail. */ 01266 ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno)); 01267 01268 return -1; 01269 } 01270 elapsed = ast_tvdiff_ms(ast_tvnow(), start); 01271 if (elapsed >= timeoutms) { 01272 return -1; 01273 } 01274 } 01275 01276 return 0; 01277 }
| 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.
| string | String to be converted | |
| outbuf | Resulting encoded string | |
| buflen | Size of output buffer |
Definition at line 471 of file utils.c.
References ast_assert, entity, and len().
Referenced by state_notify_build_xml().
00472 { 00473 char *dst = outbuf; 00474 char *end = outbuf + buflen - 1; /* save one for the null terminator */ 00475 00476 /* Handle the case for the empty output buffer */ 00477 if (buflen == 0) { 00478 return -1; 00479 } 00480 00481 /* Escaping rules from http://www.w3.org/TR/REC-xml/#syntax */ 00482 /* This also prevents partial entities at the end of a string */ 00483 while (*string && dst < end) { 00484 const char *entity = NULL; 00485 int len = 0; 00486 00487 switch (*string) { 00488 case '<': 00489 entity = "<"; 00490 len = 4; 00491 break; 00492 case '&': 00493 entity = "&"; 00494 len = 5; 00495 break; 00496 case '>': 00497 /* necessary if ]]> is in the string; easier to escape them all */ 00498 entity = ">"; 00499 len = 4; 00500 break; 00501 case '\'': 00502 /* necessary in single-quoted strings; easier to escape them all */ 00503 entity = "'"; 00504 len = 6; 00505 break; 00506 case '"': 00507 /* necessary in double-quoted strings; easier to escape them all */ 00508 entity = """; 00509 len = 6; 00510 break; 00511 default: 00512 *dst++ = *string++; 00513 break; 00514 } 00515 00516 if (entity) { 00517 ast_assert(len == strlen(entity)); 00518 if (end - dst < len) { 00519 /* no room for the entity; stop */ 00520 break; 00521 } 00522 /* just checked for length; strcpy is fine */ 00523 strcpy(dst, entity); 00524 dst += len; 00525 ++string; 00526 } 00527 } 00528 /* Write null terminator */ 00529 *dst = '\0'; 00530 /* If any chars are left in string, return failure */ 00531 return *string == '\0' ? 0 : -1; 00532 }
| static void base64_init | ( | void | ) | [static] |
Definition at line 355 of file utils.c.
Referenced by ast_utils_init().
00356 { 00357 int x; 00358 memset(b2a, -1, sizeof(b2a)); 00359 /* Initialize base-64 Conversion table */ 00360 for (x = 0; x < 26; x++) { 00361 /* A-Z */ 00362 base64[x] = 'A' + x; 00363 b2a['A' + x] = x; 00364 /* a-z */ 00365 base64[x + 26] = 'a' + x; 00366 b2a['a' + x] = x + 26; 00367 /* 0-9 */ 00368 if (x < 10) { 00369 base64[x + 52] = '0' + x; 00370 b2a['0' + x] = x + 52; 00371 } 00372 } 00373 base64[62] = '+'; 00374 base64[63] = '/'; 00375 b2a[(int)'+'] = 62; 00376 b2a[(int)'/'] = 63; 00377 }
| static void* dummy_start | ( | void * | data | ) | [static] |
Definition at line 1111 of file utils.c.
References ast_free, AST_LIST_INSERT_TAIL, AST_MUTEX_KIND, ast_register_thread(), ast_threadstorage_get(), ast_unregister_thread(), thr_arg::data, thr_arg::name, pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock, thr_arg::start_routine, and strdup.
Referenced by ast_pthread_create_stack().
01112 { 01113 void *ret; 01114 struct thr_arg a = *((struct thr_arg *) data); /* make a local copy */ 01115 #ifdef DEBUG_THREADS 01116 struct thr_lock_info *lock_info; 01117 pthread_mutexattr_t mutex_attr; 01118 01119 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info)))) 01120 return NULL; 01121 01122 lock_info->thread_id = pthread_self(); 01123 lock_info->thread_name = strdup(a.name); 01124 01125 pthread_mutexattr_init(&mutex_attr); 01126 pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND); 01127 pthread_mutex_init(&lock_info->lock, &mutex_attr); 01128 pthread_mutexattr_destroy(&mutex_attr); 01129 01130 pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */ 01131 AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry); 01132 pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */ 01133 #endif /* DEBUG_THREADS */ 01134 01135 /* note that even though data->name is a pointer to allocated memory, 01136 we are not freeing it here because ast_register_thread is going to 01137 keep a copy of the pointer and then ast_unregister_thread will 01138 free the memory 01139 */ 01140 ast_free(data); 01141 ast_register_thread(a.name); 01142 pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self()); 01143 01144 ret = a.start_routine(a.data); 01145 01146 pthread_cleanup_pop(1); 01147 01148 return ret; 01149 }
| static size_t optimal_alloc_size | ( | size_t | size | ) | [static] |
Definition at line 1682 of file utils.c.
References ALLOCATOR_OVERHEAD.
Referenced by __ast_calloc_with_stringfields(), and add_string_pool().
01683 { 01684 unsigned int count; 01685 01686 size += ALLOCATOR_OVERHEAD; 01687 01688 for (count = 1; size; size >>= 1, count++); 01689 01690 return (1 << count) - ALLOCATOR_OVERHEAD; 01691 }
| static struct timeval tvfix | ( | struct timeval | a | ) | [static, read] |
Definition at line 1525 of file utils.c.
References ast_log(), LOG_WARNING, and ONE_MILLION.
Referenced by ast_tvadd(), and ast_tvsub().
01526 { 01527 if (a.tv_usec >= ONE_MILLION) { 01528 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n", 01529 (long)a.tv_sec, (long int) a.tv_usec); 01530 a.tv_sec += a.tv_usec / ONE_MILLION; 01531 a.tv_usec %= ONE_MILLION; 01532 } else if (a.tv_usec < 0) { 01533 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n", 01534 (long)a.tv_sec, (long int) a.tv_usec); 01535 a.tv_usec = 0; 01536 } 01537 return a; 01538 }
struct { ... } __ast_string_field_empty_buffer [static] |
Definition at line 1674 of file utils.c.
Referenced by __ast_calloc_with_stringfields().
char base64[64] [static] |
Definition at line 71 of file utils.c.
Referenced by aji_start_sasl().
int dev_urandom_fd [static] |
ast_mutex_t fetchadd_m = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 2009 of file utils.c.
Referenced by ast_atomic_fetchadd_int_slow().
struct ast_threadstorage inet_ntoa_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_inet_ntoa_buf , .custom_init = NULL , } [static] |
Definition at line 74 of file utils.c.
Referenced by ast_inet_ntoa().
ast_mutex_t randomlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
glibc puts a lock inside random(3), so that the results are thread-safe. BSD libc (and others) do not.
Definition at line 1590 of file utils.c.
Referenced by ast_random().
| char string[1] |
Definition at line 1675 of file utils.c.
Referenced by private_enum_init().
1.6.1