Wed Mar 4 19:58:15 2009

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 /*!
00223  * \brief thread-safe replacement for inet_ntoa().
00224  *
00225  * \note It is very important to note that even though this is a thread-safe
00226  *       replacement for inet_ntoa(), it is *not* reentrant.  In a single
00227  *       thread, the result from a previous call to this function is no longer
00228  *       valid once it is called again.  If the result from multiple calls to
00229  *       this function need to be kept or used at once, then the result must be
00230  *       copied to a local buffer before calling this function again.
00231  */
00232 const char *ast_inet_ntoa(struct in_addr ia);
00233 
00234 #ifdef inet_ntoa
00235 #undef inet_ntoa
00236 #endif
00237 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
00238 
00239 #ifdef localtime_r
00240 #undef localtime_r
00241 #endif
00242 #define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
00243 
00244 int ast_utils_init(void);
00245 int ast_wait_for_input(int fd, int ms);
00246 
00247 /*! ast_carefulwrite
00248    \brief Try to write string, but wait no more than ms milliseconds
00249    before timing out.
00250 
00251    \note If you are calling ast_carefulwrite, it is assumed that you are calling
00252    it on a file descriptor that _DOES_ have NONBLOCK set.  This way,
00253    there is only one system call made to do a write, unless we actually
00254    have a need to wait.  This way, we get better performance.
00255 */
00256 int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
00257 
00258 /*! Compares the source address and port of two sockaddr_in */
00259 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
00260 {
00261    return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) 
00262       || (sin1->sin_port != sin2->sin_port));
00263 }
00264 
00265 #define AST_STACKSIZE 240 * 1024
00266 
00267 #if defined(LOW_MEMORY)
00268 #define AST_BACKGROUND_STACKSIZE 48 * 1024
00269 #else
00270 #define AST_BACKGROUND_STACKSIZE 240 * 1024
00271 #endif
00272 
00273 void ast_register_thread(char *name);
00274 void ast_unregister_thread(void *id);
00275 
00276 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
00277               void *data, size_t stacksize, const char *file, const char *caller,
00278               int line, const char *start_fn);
00279 
00280 #define ast_pthread_create(a, b, c, d) ast_pthread_create_stack(a, b, c, d,         \
00281                              0,           \
00282                              __FILE__, __FUNCTION__,     \
00283                              __LINE__, #c)
00284 
00285 #define ast_pthread_create_background(a, b, c, d) ast_pthread_create_stack(a, b, c, d,       \
00286                               AST_BACKGROUND_STACKSIZE,  \
00287                               __FILE__, __FUNCTION__, \
00288                               __LINE__, #c)
00289 
00290 /*!
00291    \brief Process a string to find and replace characters
00292    \param start The string to analyze
00293    \param find The character to find
00294    \param replace_with The character that will replace the one we are looking for
00295 */
00296 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
00297 
00298 #ifdef linux
00299 #define ast_random random
00300 #else
00301 long int ast_random(void);
00302 #endif
00303 
00304 /*! 
00305  * \brief free() wrapper
00306  *
00307  * ast_free should be used when a function pointer for free() needs to be passed
00308  * as the argument to a function. Otherwise, astmm will cause seg faults.
00309  */
00310 #ifdef __AST_DEBUG_MALLOC
00311 static void ast_free(void *ptr) attribute_unused;
00312 static void ast_free(void *ptr)
00313 {
00314    free(ptr);
00315 }
00316 #else
00317 #define ast_free free
00318 #endif
00319 
00320 #ifndef __AST_DEBUG_MALLOC
00321 
00322 #define MALLOC_FAILURE_MSG \
00323    ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
00324 /*!
00325  * \brief A wrapper for malloc()
00326  *
00327  * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
00328  * message in the case that the allocation fails.
00329  *
00330  * The argument and return value are the same as malloc()
00331  */
00332 #define ast_malloc(len) \
00333    _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00334 
00335 AST_INLINE_API(
00336 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
00337 {
00338    void *p;
00339 
00340    if (!(p = malloc(len)))
00341       MALLOC_FAILURE_MSG;
00342 
00343    return p;
00344 }
00345 )
00346 
00347 /*!
00348  * \brief A wrapper for calloc()
00349  *
00350  * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
00351  * message in the case that the allocation fails.
00352  *
00353  * The arguments and return value are the same as calloc()
00354  */
00355 #define ast_calloc(num, len) \
00356    _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00357 
00358 AST_INLINE_API(
00359 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
00360 {
00361    void *p;
00362 
00363    if (!(p = calloc(num, len)))
00364       MALLOC_FAILURE_MSG;
00365 
00366    return p;
00367 }
00368 )
00369 
00370 /*!
00371  * \brief A wrapper for calloc() for use in cache pools
00372  *
00373  * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
00374  * message in the case that the allocation fails. When memory debugging is in use,
00375  * the memory allocated by this function will be marked as 'cache' so it can be
00376  * distinguished from normal memory allocations.
00377  *
00378  * The arguments and return value are the same as calloc()
00379  */
00380 #define ast_calloc_cache(num, len) \
00381    _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00382 
00383 /*!
00384  * \brief A wrapper for realloc()
00385  *
00386  * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
00387  * message in the case that the allocation fails.
00388  *
00389  * The arguments and return value are the same as realloc()
00390  */
00391 #define ast_realloc(p, len) \
00392    _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00393 
00394 AST_INLINE_API(
00395 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
00396 {
00397    void *newp;
00398 
00399    if (!(newp = realloc(p, len)))
00400       MALLOC_FAILURE_MSG;
00401 
00402    return newp;
00403 }
00404 )
00405 
00406 /*!
00407  * \brief A wrapper for strdup()
00408  *
00409  * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
00410  * message in the case that the allocation fails.
00411  *
00412  * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
00413  * argument is provided, ast_strdup will return NULL without generating any
00414  * kind of error log message.
00415  *
00416  * The argument and return value are the same as strdup()
00417  */
00418 #define ast_strdup(str) \
00419    _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00420 
00421 AST_INLINE_API(
00422 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
00423 {
00424    char *newstr = NULL;
00425 
00426    if (str) {
00427       if (!(newstr = strdup(str)))
00428          MALLOC_FAILURE_MSG;
00429    }
00430 
00431    return newstr;
00432 }
00433 )
00434 
00435 /*!
00436  * \brief A wrapper for strndup()
00437  *
00438  * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
00439  * message in the case that the allocation fails.
00440  *
00441  * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
00442  * string to duplicate. If a NULL argument is provided, ast_strdup will return  
00443  * NULL without generating any kind of error log message.
00444  *
00445  * The arguments and return value are the same as strndup()
00446  */
00447 #define ast_strndup(str, len) \
00448    _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00449 
00450 AST_INLINE_API(
00451 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
00452 {
00453    char *newstr = NULL;
00454 
00455    if (str) {
00456       if (!(newstr = strndup(str, len)))
00457          MALLOC_FAILURE_MSG;
00458    }
00459 
00460    return newstr;
00461 }
00462 )
00463 
00464 /*!
00465  * \brief A wrapper for asprintf()
00466  *
00467  * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
00468  * message in the case that the allocation fails.
00469  *
00470  * The arguments and return value are the same as asprintf()
00471  */
00472 #define ast_asprintf(ret, fmt, ...) \
00473    _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
00474 
00475 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...) __attribute__((format(printf, 5, 6)));
00476 
00477 /*!
00478  * \brief A wrapper for vasprintf()
00479  *
00480  * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
00481  * message in the case that the allocation fails.
00482  *
00483  * The arguments and return value are the same as vasprintf()
00484  */
00485 #define ast_vasprintf(ret, fmt, ap) \
00486    _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
00487 
00488 AST_INLINE_API(
00489 int __attribute__((format(printf, 5, 0))) _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
00490 {
00491    int res;
00492 
00493    if ((res = vasprintf(ret, fmt, ap)) == -1)
00494       MALLOC_FAILURE_MSG;
00495 
00496    return res;
00497 }
00498 )
00499 
00500 #else
00501 
00502 /* If astmm is in use, let it handle these.  Otherwise, it will report that
00503    all allocations are coming from this header file */
00504 
00505 #define ast_malloc(a)      malloc(a)
00506 #define ast_calloc(a,b)    calloc(a,b)
00507 #define ast_realloc(a,b)   realloc(a,b)
00508 #define ast_strdup(a)      strdup(a)
00509 #define ast_strndup(a,b)   strndup(a,b)
00510 #define ast_asprintf(a,b,...) asprintf(a,b,__VA_ARGS__)
00511 #define ast_vasprintf(a,b,c)  vasprintf(a,b,c)
00512 
00513 #endif /* AST_DEBUG_MALLOC */
00514 
00515 #if !defined(ast_strdupa) && defined(__GNUC__)
00516 /*!
00517   \brief duplicate a string in memory from the stack
00518   \param s The string to duplicate
00519 
00520   This macro will duplicate the given string.  It returns a pointer to the stack
00521   allocatted memory for the new string.
00522 */
00523 #define ast_strdupa(s)                                                    \
00524    (__extension__                                                    \
00525    ({                                                                \
00526       const char *__old = (s);                                  \
00527       size_t __len = strlen(__old) + 1;                         \
00528       char *__new = __builtin_alloca(__len);                    \
00529       memcpy (__new, __old, __len);                             \
00530       __new;                                                    \
00531    }))
00532 #endif
00533 
00534 /*!
00535   \brief Disable PMTU discovery on a socket
00536   \param sock The socket to manipulate
00537   \return Nothing
00538 
00539   On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
00540   bit set. This is supposedly done to allow the application to do PMTU
00541   discovery, but Asterisk does not do this.
00542 
00543   Because of this, UDP packets sent by Asterisk that are larger than the MTU
00544   of any hop in the path will be lost. This function can be called on a socket
00545   to ensure that the DF bit will not be set.
00546  */
00547 void ast_enable_packet_fragmentation(int sock);
00548 
00549 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
00550 
00551 #ifdef AST_DEVMODE
00552 #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00553 static void force_inline _ast_assert(int condition, const char *condition_str, 
00554    const char *file, int line, const char *function)
00555 {
00556    if (__builtin_expect(!condition, 1)) {
00557       /* Attempt to put it into the logger, but hope that at least someone saw the
00558        * message on stderr ... */
00559       ast_log(LOG_ERROR, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
00560          condition_str, condition, line, function, file);
00561       fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
00562          condition_str, condition, line, function, file);
00563       /* Give the logger a chance to get the message out, just in case we abort(), or
00564        * Asterisk crashes due to whatever problem just happened after we exit ast_assert(). */
00565       usleep(1);
00566 #ifdef DO_CRASH
00567       abort();
00568       /* Just in case abort() doesn't work or something else super silly,
00569        * and for Qwell's amusement. */
00570       *((int*)0)=0;
00571 #endif
00572    }
00573 }
00574 #else
00575 #define ast_assert(a)
00576 #endif
00577 
00578 #endif /* _ASTERISK_UTILS_H */

Generated on Wed Mar 4 19:58:15 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7