Sat Aug 6 00:39:33 2011

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 (((sizeof(void *) * 8 * 8) - 16) * 1024)
00266 
00267 #if defined(LOW_MEMORY)
00268 #define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
00269 #else
00270 #define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
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_ptr 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_ptr(void *ptr) attribute_unused;
00312 static void ast_free_ptr(void *ptr)
00313 {
00314    free(ptr);
00315 }
00316 #else
00317 #define ast_free free
00318 #define ast_free_ptr ast_free
00319 #endif
00320 
00321 #ifndef __AST_DEBUG_MALLOC
00322 
00323 #define MALLOC_FAILURE_MSG \
00324    ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
00325 /*!
00326  * \brief A wrapper for malloc()
00327  *
00328  * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
00329  * message in the case that the allocation fails.
00330  *
00331  * The argument and return value are the same as malloc()
00332  */
00333 #define ast_malloc(len) \
00334    _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00335 
00336 AST_INLINE_API(
00337 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
00338 {
00339    void *p;
00340 
00341    if (!(p = malloc(len)))
00342       MALLOC_FAILURE_MSG;
00343 
00344    return p;
00345 }
00346 )
00347 
00348 /*!
00349  * \brief A wrapper for calloc()
00350  *
00351  * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
00352  * message in the case that the allocation fails.
00353  *
00354  * The arguments and return value are the same as calloc()
00355  */
00356 #define ast_calloc(num, len) \
00357    _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00358 
00359 AST_INLINE_API(
00360 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
00361 {
00362    void *p;
00363 
00364    if (!(p = calloc(num, len)))
00365       MALLOC_FAILURE_MSG;
00366 
00367    return p;
00368 }
00369 )
00370 
00371 /*!
00372  * \brief A wrapper for calloc() for use in cache pools
00373  *
00374  * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
00375  * message in the case that the allocation fails. When memory debugging is in use,
00376  * the memory allocated by this function will be marked as 'cache' so it can be
00377  * distinguished from normal memory allocations.
00378  *
00379  * The arguments and return value are the same as calloc()
00380  */
00381 #define ast_calloc_cache(num, len) \
00382    _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00383 
00384 /*!
00385  * \brief A wrapper for realloc()
00386  *
00387  * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
00388  * message in the case that the allocation fails.
00389  *
00390  * The arguments and return value are the same as realloc()
00391  */
00392 #define ast_realloc(p, len) \
00393    _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00394 
00395 AST_INLINE_API(
00396 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
00397 {
00398    void *newp;
00399 
00400    if (!(newp = realloc(p, len)))
00401       MALLOC_FAILURE_MSG;
00402 
00403    return newp;
00404 }
00405 )
00406 
00407 /*!
00408  * \brief A wrapper for strdup()
00409  *
00410  * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
00411  * message in the case that the allocation fails.
00412  *
00413  * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
00414  * argument is provided, ast_strdup will return NULL without generating any
00415  * kind of error log message.
00416  *
00417  * The argument and return value are the same as strdup()
00418  */
00419 #define ast_strdup(str) \
00420    _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00421 
00422 AST_INLINE_API(
00423 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
00424 {
00425    char *newstr = NULL;
00426 
00427    if (str) {
00428       if (!(newstr = strdup(str)))
00429          MALLOC_FAILURE_MSG;
00430    }
00431 
00432    return newstr;
00433 }
00434 )
00435 
00436 /*!
00437  * \brief A wrapper for strndup()
00438  *
00439  * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
00440  * message in the case that the allocation fails.
00441  *
00442  * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
00443  * string to duplicate. If a NULL argument is provided, ast_strdup will return  
00444  * NULL without generating any kind of error log message.
00445  *
00446  * The arguments and return value are the same as strndup()
00447  */
00448 #define ast_strndup(str, len) \
00449    _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00450 
00451 AST_INLINE_API(
00452 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
00453 {
00454    char *newstr = NULL;
00455 
00456    if (str) {
00457       if (!(newstr = strndup(str, len)))
00458          MALLOC_FAILURE_MSG;
00459    }
00460 
00461    return newstr;
00462 }
00463 )
00464 
00465 /*!
00466  * \brief A wrapper for asprintf()
00467  *
00468  * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
00469  * message in the case that the allocation fails.
00470  *
00471  * The arguments and return value are the same as asprintf()
00472  */
00473 #define ast_asprintf(ret, fmt, ...) \
00474    _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
00475 
00476 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...) __attribute__((format(printf, 5, 6)));
00477 
00478 /*!
00479  * \brief A wrapper for vasprintf()
00480  *
00481  * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
00482  * message in the case that the allocation fails.
00483  *
00484  * The arguments and return value are the same as vasprintf()
00485  */
00486 #define ast_vasprintf(ret, fmt, ap) \
00487    _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
00488 
00489 AST_INLINE_API(
00490 int __attribute__((format(printf, 5, 0))) _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
00491 {
00492    int res;
00493 
00494    if ((res = vasprintf(ret, fmt, ap)) == -1)
00495       MALLOC_FAILURE_MSG;
00496 
00497    return res;
00498 }
00499 )
00500 
00501 #endif /* AST_DEBUG_MALLOC */
00502 
00503 #if !defined(ast_strdupa) && defined(__GNUC__)
00504 /*!
00505   \brief duplicate a string in memory from the stack
00506   \param s The string to duplicate
00507 
00508   This macro will duplicate the given string.  It returns a pointer to the stack
00509   allocatted memory for the new string.
00510 */
00511 #define ast_strdupa(s)                                                    \
00512    (__extension__                                                    \
00513    ({                                                                \
00514       const char *__old = (s);                                  \
00515       size_t __len = strlen(__old) + 1;                         \
00516       char *__new = __builtin_alloca(__len);                    \
00517       memcpy (__new, __old, __len);                             \
00518       __new;                                                    \
00519    }))
00520 #endif
00521 
00522 /*!
00523   \brief Disable PMTU discovery on a socket
00524   \param sock The socket to manipulate
00525   \return Nothing
00526 
00527   On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
00528   bit set. This is supposedly done to allow the application to do PMTU
00529   discovery, but Asterisk does not do this.
00530 
00531   Because of this, UDP packets sent by Asterisk that are larger than the MTU
00532   of any hop in the path will be lost. This function can be called on a socket
00533   to ensure that the DF bit will not be set.
00534  */
00535 void ast_enable_packet_fragmentation(int sock);
00536 
00537 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
00538 
00539 #ifdef AST_DEVMODE
00540 #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00541 static void force_inline _ast_assert(int condition, const char *condition_str, 
00542    const char *file, int line, const char *function)
00543 {
00544    if (__builtin_expect(!condition, 1)) {
00545       /* Attempt to put it into the logger, but hope that at least someone saw the
00546        * message on stderr ... */
00547       ast_log(LOG_ERROR, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
00548          condition_str, condition, line, function, file);
00549       fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
00550          condition_str, condition, line, function, file);
00551       /* Give the logger a chance to get the message out, just in case we abort(), or
00552        * Asterisk crashes due to whatever problem just happened after we exit ast_assert(). */
00553       usleep(1);
00554 #ifdef DO_CRASH
00555       abort();
00556       /* Just in case abort() doesn't work or something else super silly,
00557        * and for Qwell's amusement. */
00558       *((int*)0)=0;
00559 #endif
00560    }
00561 }
00562 #else
00563 #define ast_assert(a)
00564 #endif
00565 
00566 /*!\brief Resolve a binary to a full pathname
00567  * \param binary Name of the executable to resolve
00568  * \param fullpath Buffer to hold the complete pathname
00569  * \param fullpath_size Size of \a fullpath
00570  * \retval NULL \a binary was not found or the environment variable PATH is not set
00571  * \return \a fullpath
00572  */
00573 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size);
00574 
00575 #endif /* _ASTERISK_UTILS_H */

Generated on Sat Aug 6 00:39:33 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7