![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
utils.h
Go to the documentation of this file.
00001 /* 00002 * Asterisk -- An open source telephony toolkit. 00003 * 00004 * Copyright (C) 1999 - 2006, Digium, Inc. 00005 * 00006 * Mark Spencer <markster@digium.com> 00007 * 00008 * See http://www.asterisk.org for more information about 00009 * the Asterisk project. Please do not directly contact 00010 * any of the maintainers of this project for assistance; 00011 * the project provides a web site, mailing lists and IRC 00012 * channels for your use. 00013 * 00014 * This program is free software, distributed under the terms of 00015 * the GNU General Public License Version 2. See the LICENSE file 00016 * at the top of the source tree. 00017 */ 00018 00019 /*! \file 00020 * \brief Utility functions 00021 */ 00022 00023 #ifndef _ASTERISK_UTILS_H 00024 #define _ASTERISK_UTILS_H 00025 00026 #include "asterisk/compat.h" 00027 00028 #include <stdlib.h> 00029 #include <stdio.h> 00030 #include <stdarg.h> 00031 #include <netinet/in.h> 00032 #include <arpa/inet.h> /* we want to override inet_ntoa */ 00033 #include <netdb.h> 00034 #include <limits.h> 00035 #include <string.h> 00036 00037 #include "asterisk/lock.h" 00038 #include "asterisk/time.h" 00039 #include "asterisk/logger.h" 00040 #include "asterisk/compiler.h" 00041 00042 /*! \note 00043 \verbatim 00044 Note: 00045 It is very important to use only unsigned variables to hold 00046 bit flags, as otherwise you can fall prey to the compiler's 00047 sign-extension antics if you try to use the top two bits in 00048 your variable. 00049 00050 The flag macros below use a set of compiler tricks to verify 00051 that the caller is using an "unsigned int" variable to hold 00052 the flags, and nothing else. If the caller uses any other 00053 type of variable, a warning message similar to this: 00054 00055 warning: comparison of distinct pointer types lacks cast 00056 will be generated. 00057 00058 The "dummy" variable below is used to make these comparisons. 00059 00060 Also note that at -O2 or above, this type-safety checking 00061 does _not_ produce any additional object code at all. 00062 \endverbatim 00063 */ 00064 00065 extern unsigned int __unsigned_int_flags_dummy; 00066 00067 #define ast_test_flag(p,flag) ({ \ 00068 typeof ((p)->flags) __p = (p)->flags; \ 00069 typeof (__unsigned_int_flags_dummy) __x = 0; \ 00070 (void) (&__p == &__x); \ 00071 ((p)->flags & (flag)); \ 00072 }) 00073 00074 #define ast_set_flag(p,flag) do { \ 00075 typeof ((p)->flags) __p = (p)->flags; \ 00076 typeof (__unsigned_int_flags_dummy) __x = 0; \ 00077 (void) (&__p == &__x); \ 00078 ((p)->flags |= (flag)); \ 00079 } while(0) 00080 00081 #define ast_clear_flag(p,flag) do { \ 00082 typeof ((p)->flags) __p = (p)->flags; \ 00083 typeof (__unsigned_int_flags_dummy) __x = 0; \ 00084 (void) (&__p == &__x); \ 00085 ((p)->flags &= ~(flag)); \ 00086 } while(0) 00087 00088 #define ast_copy_flags(dest,src,flagz) do { \ 00089 typeof ((dest)->flags) __d = (dest)->flags; \ 00090 typeof ((src)->flags) __s = (src)->flags; \ 00091 typeof (__unsigned_int_flags_dummy) __x = 0; \ 00092 (void) (&__d == &__x); \ 00093 (void) (&__s == &__x); \ 00094 (dest)->flags &= ~(flagz); \ 00095 (dest)->flags |= ((src)->flags & (flagz)); \ 00096 } while (0) 00097 00098 #define ast_set2_flag(p,value,flag) do { \ 00099 typeof ((p)->flags) __p = (p)->flags; \ 00100 typeof (__unsigned_int_flags_dummy) __x = 0; \ 00101 (void) (&__p == &__x); \ 00102 if (value) \ 00103 (p)->flags |= (flag); \ 00104 else \ 00105 (p)->flags &= ~(flag); \ 00106 } while (0) 00107 00108 #define ast_set_flags_to(p,flag,value) do { \ 00109 typeof ((p)->flags) __p = (p)->flags; \ 00110 typeof (__unsigned_int_flags_dummy) __x = 0; \ 00111 (void) (&__p == &__x); \ 00112 (p)->flags &= ~(flag); \ 00113 (p)->flags |= (value); \ 00114 } while (0) 00115 00116 /* Non-type checking variations for non-unsigned int flags. You 00117 should only use non-unsigned int flags where required by 00118 protocol etc and if you know what you're doing :) */ 00119 #define ast_test_flag_nonstd(p,flag) \ 00120 ((p)->flags & (flag)) 00121 00122 #define ast_set_flag_nonstd(p,flag) do { \ 00123 ((p)->flags |= (flag)); \ 00124 } while(0) 00125 00126 #define ast_clear_flag_nonstd(p,flag) do { \ 00127 ((p)->flags &= ~(flag)); \ 00128 } while(0) 00129 00130 #define ast_copy_flags_nonstd(dest,src,flagz) do { \ 00131 (dest)->flags &= ~(flagz); \ 00132 (dest)->flags |= ((src)->flags & (flagz)); \ 00133 } while (0) 00134 00135 #define ast_set2_flag_nonstd(p,value,flag) do { \ 00136 if (value) \ 00137 (p)->flags |= (flag); \ 00138 else \ 00139 (p)->flags &= ~(flag); \ 00140 } while (0) 00141 00142 #define AST_FLAGS_ALL UINT_MAX 00143 00144 struct ast_flags { 00145 unsigned int flags; 00146 }; 00147 00148 struct ast_hostent { 00149 struct hostent hp; 00150 char buf[1024]; 00151 }; 00152 00153 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp); 00154 00155 /* ast_md5_hash 00156 \brief Produces MD5 hash based on input string */ 00157 void ast_md5_hash(char *output, char *input); 00158 /* ast_sha1_hash 00159 \brief Produces SHA1 hash based on input string */ 00160 void ast_sha1_hash(char *output, char *input); 00161 00162 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks); 00163 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max); 00164 int ast_base64decode(unsigned char *dst, const char *src, int max); 00165 00166 /*! ast_uri_encode 00167 \brief Turn text string to URI-encoded %XX version 00168 At this point, we're converting from ISO-8859-x (8-bit), not UTF8 00169 as in the SIP protocol spec 00170 If doreserved == 1 we will convert reserved characters also. 00171 RFC 2396, section 2.4 00172 outbuf needs to have more memory allocated than the instring 00173 to have room for the expansion. Every char that is converted 00174 is replaced by three ASCII characters. 00175 \param string String to be converted 00176 \param outbuf Resulting encoded string 00177 \param buflen Size of output buffer 00178 \param doreserved Convert reserved characters 00179 */ 00180 00181 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved); 00182 00183 /*! \brief Decode URI, URN, URL (overwrite string) 00184 \param s String to be decoded 00185 */ 00186 void ast_uri_decode(char *s); 00187 00188 static force_inline void ast_slinear_saturated_add(short *input, short *value) 00189 { 00190 int res; 00191 00192 res = (int) *input + *value; 00193 if (res > 32767) 00194 *input = 32767; 00195 else if (res < -32767) 00196 *input = -32767; 00197 else 00198 *input = (short) res; 00199 } 00200 00201 static force_inline void ast_slinear_saturated_multiply(short *input, short *value) 00202 { 00203 int res; 00204 00205 res = (int) *input * *value; 00206 if (res > 32767) 00207 *input = 32767; 00208 else if (res < -32767) 00209 *input = -32767; 00210 else 00211 *input = (short) res; 00212 } 00213 00214 static force_inline void ast_slinear_saturated_divide(short *input, short *value) 00215 { 00216 *input /= *value; 00217 } 00218 00219 int test_for_thread_safety(void); 00220 00221 /*! 00222 * \brief thread-safe replacement for inet_ntoa(). 00223 * 00224 * \note It is very important to note that even though this is a thread-safe 00225 * replacement for inet_ntoa(), it is *not* reentrant. In a single 00226 * thread, the result from a previous call to this function is no longer 00227 * valid once it is called again. If the result from multiple calls to 00228 * this function need to be kept or used at once, then the result must be 00229 * copied to a local buffer before calling this function again. 00230 */ 00231 const char *ast_inet_ntoa(struct in_addr ia); 00232 00233 #ifdef inet_ntoa 00234 #undef inet_ntoa 00235 #endif 00236 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__ 00237 00238 int ast_utils_init(void); 00239 int ast_wait_for_input(int fd, int ms); 00240 00241 /*! ast_carefulwrite 00242 \brief Try to write string, but wait no more than ms milliseconds 00243 before timing out. 00244 00245 \note If you are calling ast_carefulwrite, it is assumed that you are calling 00246 it on a file descriptor that _DOES_ have NONBLOCK set. This way, 00247 there is only one system call made to do a write, unless we actually 00248 have a need to wait. This way, we get better performance. 00249 */ 00250 int ast_carefulwrite(int fd, char *s, int len, int timeoutms); 00251 00252 /*! Compares the source address and port of two sockaddr_in */ 00253 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2) 00254 { 00255 return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) 00256 || (sin1->sin_port != sin2->sin_port)); 00257 } 00258 00259 #define AST_STACKSIZE 240 * 1024 00260 00261 #if defined(LOW_MEMORY) 00262 #define AST_BACKGROUND_STACKSIZE 48 * 1024 00263 #else 00264 #define AST_BACKGROUND_STACKSIZE 240 * 1024 00265 #endif 00266 00267 void ast_register_thread(char *name); 00268 void ast_unregister_thread(void *id); 00269 00270 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), 00271 void *data, size_t stacksize, const char *file, const char *caller, 00272 int line, const char *start_fn); 00273 00274 #define ast_pthread_create(a, b, c, d) ast_pthread_create_stack(a, b, c, d, \ 00275 0, \ 00276 __FILE__, __FUNCTION__, \ 00277 __LINE__, #c) 00278 00279 #define ast_pthread_create_background(a, b, c, d) ast_pthread_create_stack(a, b, c, d, \ 00280 AST_BACKGROUND_STACKSIZE, \ 00281 __FILE__, __FUNCTION__, \ 00282 __LINE__, #c) 00283 00284 /*! 00285 \brief Process a string to find and replace characters 00286 \param start The string to analyze 00287 \param find The character to find 00288 \param replace_with The character that will replace the one we are looking for 00289 */ 00290 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with); 00291 00292 #ifdef linux 00293 #define ast_random random 00294 #else 00295 long int ast_random(void); 00296 #endif 00297 00298 /*! 00299 * \brief free() wrapper 00300 * 00301 * ast_free should be used when a function pointer for free() needs to be passed 00302 * as the argument to a function. Otherwise, astmm will cause seg faults. 00303 */ 00304 #ifdef __AST_DEBUG_MALLOC 00305 static void ast_free(void *ptr) attribute_unused; 00306 static void ast_free(void *ptr) 00307 { 00308 free(ptr); 00309 } 00310 #else 00311 #define ast_free free 00312 #endif 00313 00314 #ifndef __AST_DEBUG_MALLOC 00315 00316 #define MALLOC_FAILURE_MSG \ 00317 ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file); 00318 /*! 00319 * \brief A wrapper for malloc() 00320 * 00321 * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log 00322 * message in the case that the allocation fails. 00323 * 00324 * The argument and return value are the same as malloc() 00325 */ 00326 #define ast_malloc(len) \ 00327 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__) 00328 00329 AST_INLINE_API( 00330 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func), 00331 { 00332 void *p; 00333 00334 if (!(p = malloc(len))) 00335 MALLOC_FAILURE_MSG; 00336 00337 return p; 00338 } 00339 ) 00340 00341 /*! 00342 * \brief A wrapper for calloc() 00343 * 00344 * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log 00345 * message in the case that the allocation fails. 00346 * 00347 * The arguments and return value are the same as calloc() 00348 */ 00349 #define ast_calloc(num, len) \ 00350 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) 00351 00352 AST_INLINE_API( 00353 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func), 00354 { 00355 void *p; 00356 00357 if (!(p = calloc(num, len))) 00358 MALLOC_FAILURE_MSG; 00359 00360 return p; 00361 } 00362 ) 00363 00364 /*! 00365 * \brief A wrapper for calloc() for use in cache pools 00366 * 00367 * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log 00368 * message in the case that the allocation fails. When memory debugging is in use, 00369 * the memory allocated by this function will be marked as 'cache' so it can be 00370 * distinguished from normal memory allocations. 00371 * 00372 * The arguments and return value are the same as calloc() 00373 */ 00374 #define ast_calloc_cache(num, len) \ 00375 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) 00376 00377 /*! 00378 * \brief A wrapper for realloc() 00379 * 00380 * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log 00381 * message in the case that the allocation fails. 00382 * 00383 * The arguments and return value are the same as realloc() 00384 */ 00385 #define ast_realloc(p, len) \ 00386 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) 00387 00388 AST_INLINE_API( 00389 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func), 00390 { 00391 void *newp; 00392 00393 if (!(newp = realloc(p, len))) 00394 MALLOC_FAILURE_MSG; 00395 00396 return newp; 00397 } 00398 ) 00399 00400 /*! 00401 * \brief A wrapper for strdup() 00402 * 00403 * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log 00404 * message in the case that the allocation fails. 00405 * 00406 * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL 00407 * argument is provided, ast_strdup will return NULL without generating any 00408 * kind of error log message. 00409 * 00410 * The argument and return value are the same as strdup() 00411 */ 00412 #define ast_strdup(str) \ 00413 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__) 00414 00415 AST_INLINE_API( 00416 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func), 00417 { 00418 char *newstr = NULL; 00419 00420 if (str) { 00421 if (!(newstr = strdup(str))) 00422 MALLOC_FAILURE_MSG; 00423 } 00424 00425 return newstr; 00426 } 00427 ) 00428 00429 /*! 00430 * \brief A wrapper for strndup() 00431 * 00432 * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log 00433 * message in the case that the allocation fails. 00434 * 00435 * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the 00436 * string to duplicate. If a NULL argument is provided, ast_strdup will return 00437 * NULL without generating any kind of error log message. 00438 * 00439 * The arguments and return value are the same as strndup() 00440 */ 00441 #define ast_strndup(str, len) \ 00442 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) 00443 00444 AST_INLINE_API( 00445 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func), 00446 { 00447 char *newstr = NULL; 00448 00449 if (str) { 00450 if (!(newstr = strndup(str, len))) 00451 MALLOC_FAILURE_MSG; 00452 } 00453 00454 return newstr; 00455 } 00456 ) 00457 00458 /*! 00459 * \brief A wrapper for asprintf() 00460 * 00461 * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log 00462 * message in the case that the allocation fails. 00463 * 00464 * The arguments and return value are the same as asprintf() 00465 */ 00466 #define ast_asprintf(ret, fmt, ...) \ 00467 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__) 00468 00469 AST_INLINE_API( 00470 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...), 00471 { 00472 int res; 00473 va_list ap; 00474 00475 va_start(ap, fmt); 00476 if ((res = vasprintf(ret, fmt, ap)) == -1) 00477 MALLOC_FAILURE_MSG; 00478 va_end(ap); 00479 00480 return res; 00481 } 00482 ) 00483 00484 /*! 00485 * \brief A wrapper for vasprintf() 00486 * 00487 * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log 00488 * message in the case that the allocation fails. 00489 * 00490 * The arguments and return value are the same as vasprintf() 00491 */ 00492 #define ast_vasprintf(ret, fmt, ap) \ 00493 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap)) 00494 00495 AST_INLINE_API( 00496 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap), 00497 { 00498 int res; 00499 00500 if ((res = vasprintf(ret, fmt, ap)) == -1) 00501 MALLOC_FAILURE_MSG; 00502 00503 return res; 00504 } 00505 ) 00506 00507 #else 00508 00509 /* If astmm is in use, let it handle these. Otherwise, it will report that 00510 all allocations are coming from this header file */ 00511 00512 #define ast_malloc(a) malloc(a) 00513 #define ast_calloc(a,b) calloc(a,b) 00514 #define ast_realloc(a,b) realloc(a,b) 00515 #define ast_strdup(a) strdup(a) 00516 #define ast_strndup(a,b) strndup(a,b) 00517 #define ast_asprintf(a,b,c) asprintf(a,b,c) 00518 #define ast_vasprintf(a,b,c) vasprintf(a,b,c) 00519 00520 #endif /* AST_DEBUG_MALLOC */ 00521 00522 #if !defined(ast_strdupa) && defined(__GNUC__) 00523 /*! 00524 \brief duplicate a string in memory from the stack 00525 \param s The string to duplicate 00526 00527 This macro will duplicate the given string. It returns a pointer to the stack 00528 allocatted memory for the new string. 00529 */ 00530 #define ast_strdupa(s) \ 00531 (__extension__ \ 00532 ({ \ 00533 const char *__old = (s); \ 00534 size_t __len = strlen(__old) + 1; \ 00535 char *__new = __builtin_alloca(__len); \ 00536 memcpy (__new, __old, __len); \ 00537 __new; \ 00538 })) 00539 #endif 00540 00541 /*! 00542 \brief Disable PMTU discovery on a socket 00543 \param sock The socket to manipulate 00544 \return Nothing 00545 00546 On Linux, UDP sockets default to sending packets with the Dont Fragment (DF) 00547 bit set. This is supposedly done to allow the application to do PMTU 00548 discovery, but Asterisk does not do this. 00549 00550 Because of this, UDP packets sent by Asterisk that are larger than the MTU 00551 of any hop in the path will be lost. This function can be called on a socket 00552 to ensure that the DF bit will not be set. 00553 */ 00554 void ast_enable_packet_fragmentation(int sock); 00555 00556 #include "asterisk/strings.h" 00557 #endif /* _ASTERISK_UTILS_H */