Mon Jul 14 17:25:02 2008

Asterisk developer's documentation


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

Generated on Mon Jul 14 17:25:02 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1