Sat Feb 11 06:33:25 2012

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/network.h"
00027 
00028 #include <time.h> /* we want to override localtime_r */
00029 #include <unistd.h>
00030 #include <string.h>
00031 
00032 #include "asterisk/lock.h"
00033 #include "asterisk/time.h"
00034 #include "asterisk/logger.h"
00035 #include "asterisk/localtime.h"
00036 #include "asterisk/stringfields.h"
00037 
00038 /*!
00039 \note \verbatim
00040    Note:
00041    It is very important to use only unsigned variables to hold
00042    bit flags, as otherwise you can fall prey to the compiler's
00043    sign-extension antics if you try to use the top two bits in
00044    your variable.
00045 
00046    The flag macros below use a set of compiler tricks to verify
00047    that the caller is using an "unsigned int" variable to hold
00048    the flags, and nothing else. If the caller uses any other
00049    type of variable, a warning message similar to this:
00050 
00051    warning: comparison of distinct pointer types lacks cast
00052    will be generated.
00053 
00054    The "dummy" variable below is used to make these comparisons.
00055 
00056    Also note that at -O2 or above, this type-safety checking
00057    does _not_ produce any additional object code at all.
00058  \endverbatim
00059 */
00060 
00061 extern unsigned int __unsigned_int_flags_dummy;
00062 
00063 #define ast_test_flag(p,flag)       ({ \
00064                typeof ((p)->flags) __p = (p)->flags; \
00065                typeof (__unsigned_int_flags_dummy) __x = 0; \
00066                (void) (&__p == &__x); \
00067                ((p)->flags & (flag)); \
00068                })
00069 
00070 #define ast_set_flag(p,flag)     do { \
00071                typeof ((p)->flags) __p = (p)->flags; \
00072                typeof (__unsigned_int_flags_dummy) __x = 0; \
00073                (void) (&__p == &__x); \
00074                ((p)->flags |= (flag)); \
00075                } while(0)
00076 
00077 #define ast_clear_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_copy_flags(dest,src,flagz) do { \
00085                typeof ((dest)->flags) __d = (dest)->flags; \
00086                typeof ((src)->flags) __s = (src)->flags; \
00087                typeof (__unsigned_int_flags_dummy) __x = 0; \
00088                (void) (&__d == &__x); \
00089                (void) (&__s == &__x); \
00090                (dest)->flags &= ~(flagz); \
00091                (dest)->flags |= ((src)->flags & (flagz)); \
00092                } while (0)
00093 
00094 #define ast_set2_flag(p,value,flag) do { \
00095                typeof ((p)->flags) __p = (p)->flags; \
00096                typeof (__unsigned_int_flags_dummy) __x = 0; \
00097                (void) (&__p == &__x); \
00098                if (value) \
00099                   (p)->flags |= (flag); \
00100                else \
00101                   (p)->flags &= ~(flag); \
00102                } while (0)
00103 
00104 #define ast_set_flags_to(p,flag,value) do { \
00105                typeof ((p)->flags) __p = (p)->flags; \
00106                typeof (__unsigned_int_flags_dummy) __x = 0; \
00107                (void) (&__p == &__x); \
00108                (p)->flags &= ~(flag); \
00109                (p)->flags |= (value); \
00110                } while (0)
00111 
00112 
00113 /* The following 64-bit flag code can most likely be erased after app_dial
00114    is reorganized to either reduce the large number of options, or handle
00115    them in some other way. At the time of this writing, app_dial would be
00116    the only user of 64-bit option flags */
00117 
00118 extern uint64_t __unsigned_int_flags_dummy64;
00119 
00120 #define ast_test_flag64(p,flag)     ({ \
00121                typeof ((p)->flags) __p = (p)->flags; \
00122                typeof (__unsigned_int_flags_dummy64) __x = 0; \
00123                (void) (&__p == &__x); \
00124                ((p)->flags & (flag)); \
00125                })
00126 
00127 #define ast_set_flag64(p,flag)      do { \
00128                typeof ((p)->flags) __p = (p)->flags; \
00129                typeof (__unsigned_int_flags_dummy64) __x = 0; \
00130                (void) (&__p == &__x); \
00131                ((p)->flags |= (flag)); \
00132                } while(0)
00133 
00134 #define ast_clear_flag64(p,flag)       do { \
00135                typeof ((p)->flags) __p = (p)->flags; \
00136                typeof (__unsigned_int_flags_dummy64) __x = 0; \
00137                (void) (&__p == &__x); \
00138                ((p)->flags &= ~(flag)); \
00139                } while(0)
00140 
00141 #define ast_copy_flags64(dest,src,flagz)  do { \
00142                typeof ((dest)->flags) __d = (dest)->flags; \
00143                typeof ((src)->flags) __s = (src)->flags; \
00144                typeof (__unsigned_int_flags_dummy64) __x = 0; \
00145                (void) (&__d == &__x); \
00146                (void) (&__s == &__x); \
00147                (dest)->flags &= ~(flagz); \
00148                (dest)->flags |= ((src)->flags & (flagz)); \
00149                } while (0)
00150 
00151 #define ast_set2_flag64(p,value,flag)  do { \
00152                typeof ((p)->flags) __p = (p)->flags; \
00153                typeof (__unsigned_int_flags_dummy64) __x = 0; \
00154                (void) (&__p == &__x); \
00155                if (value) \
00156                   (p)->flags |= (flag); \
00157                else \
00158                   (p)->flags &= ~(flag); \
00159                } while (0)
00160 
00161 #define ast_set_flags_to64(p,flag,value)  do { \
00162                typeof ((p)->flags) __p = (p)->flags; \
00163                typeof (__unsigned_int_flags_dummy64) __x = 0; \
00164                (void) (&__p == &__x); \
00165                (p)->flags &= ~(flag); \
00166                (p)->flags |= (value); \
00167                } while (0)
00168 
00169 
00170 /* Non-type checking variations for non-unsigned int flags.  You
00171    should only use non-unsigned int flags where required by 
00172    protocol etc and if you know what you're doing :)  */
00173 #define ast_test_flag_nonstd(p,flag) \
00174                ((p)->flags & (flag))
00175 
00176 #define ast_set_flag_nonstd(p,flag)       do { \
00177                ((p)->flags |= (flag)); \
00178                } while(0)
00179 
00180 #define ast_clear_flag_nonstd(p,flag)     do { \
00181                ((p)->flags &= ~(flag)); \
00182                } while(0)
00183 
00184 #define ast_copy_flags_nonstd(dest,src,flagz)   do { \
00185                (dest)->flags &= ~(flagz); \
00186                (dest)->flags |= ((src)->flags & (flagz)); \
00187                } while (0)
00188 
00189 #define ast_set2_flag_nonstd(p,value,flag)   do { \
00190                if (value) \
00191                   (p)->flags |= (flag); \
00192                else \
00193                   (p)->flags &= ~(flag); \
00194                } while (0)
00195 
00196 #define AST_FLAGS_ALL UINT_MAX
00197 
00198 /*! \brief Structure used to handle boolean flags 
00199 */
00200 struct ast_flags {
00201    unsigned int flags;
00202 };
00203 
00204 /*! \brief Structure used to handle a large number of boolean flags == used only in app_dial?
00205 */
00206 struct ast_flags64 {
00207    uint64_t flags;
00208 };
00209 
00210 struct ast_hostent {
00211    struct hostent hp;
00212    char buf[1024];
00213 };
00214 
00215 /*! \brief Thread-safe gethostbyname function to use in Asterisk */
00216 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
00217 
00218 /*!  \brief Produces MD5 hash based on input string */
00219 void ast_md5_hash(char *output, const char *input);
00220 /*! \brief Produces SHA1 hash based on input string */
00221 void ast_sha1_hash(char *output, const char *input);
00222 
00223 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);
00224 
00225 #undef MIN
00226 #define MIN(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a > __b) ? __b : __a);})
00227 #undef MAX
00228 #define MAX(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a < __b) ? __b : __a);})
00229 
00230 /*!
00231  * \brief Encode data in base64
00232  * \param dst the destination buffer
00233  * \param src the source data to be encoded
00234  * \param srclen the number of bytes present in the source buffer
00235  * \param max the maximum number of bytes to write into the destination
00236  *        buffer, *including* the terminating NULL character.
00237  */
00238 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
00239 
00240 /*!
00241  * \brief Decode data from base64
00242  * \param dst the destination buffer
00243  * \param src the source buffer
00244  * \param max The maximum number of bytes to write into the destination
00245  *            buffer.  Note that this function will not ensure that the
00246  *            destination buffer is NULL terminated.  So, in general,
00247  *            this parameter should be sizeof(dst) - 1.
00248  */
00249 int ast_base64decode(unsigned char *dst, const char *src, int max);
00250 
00251 #define AST_URI_ALPHANUM     (1 << 0)
00252 #define AST_URI_MARK         (1 << 1)
00253 #define AST_URI_UNRESERVED   (AST_URI_ALPHANUM | AST_URI_MARK)
00254 #define AST_URI_LEGACY_SPACE (1 << 2)
00255 
00256 #define AST_URI_SIP_USER_UNRESERVED (1 << 20)
00257 
00258 extern const struct ast_flags ast_uri_http;
00259 extern const struct ast_flags ast_uri_http_legacy;
00260 extern const struct ast_flags ast_uri_sip_user;
00261 
00262 /*!
00263  * \brief Turn text string to URI-encoded %XX version
00264  *
00265  * This function encodes characters according to the rules presented in RFC
00266  * 2396 and/or RFC 3261 section 19.1.2 and section 25.1.
00267  *
00268  * Outbuf needs to have more memory allocated than the instring to have room
00269  * for the expansion. Every byte that is converted is replaced by three ASCII
00270  * characters.
00271  *
00272  * \param string string to be converted
00273  * \param outbuf resulting encoded string
00274  * \param buflen size of output buffer
00275  * \param spec flags describing how the encoding should be performed
00276  * \return a pointer to the uri encoded string
00277  */
00278 char *ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec);
00279 
00280 /*!
00281  * \brief Decode URI, URN, URL (overwrite string)
00282  *
00283  * \note The ast_uri_http_legacy decode spec flag will cause this function to
00284  * decode '+' as ' '.
00285  *
00286  * \param s string to be decoded
00287  * \param spec flags describing how the decoding should be performed
00288  */
00289 void ast_uri_decode(char *s, struct ast_flags spec);
00290 
00291 /*!
00292  * \brief Escape characters found in a quoted string.
00293  *
00294  * \note This function escapes quoted characters based on the 'qdtext' set of
00295  * allowed characters from RFC 3261 section 25.1.
00296  *
00297  * \param string string to be escaped
00298  * \param outbuf resulting escaped string
00299  * \param buflen size of output buffer
00300  * \return a pointer to the escaped string
00301  */
00302 char *ast_escape_quoted(const char *string, char *outbuf, int buflen);
00303 
00304 static force_inline void ast_slinear_saturated_add(short *input, short *value)
00305 {
00306    int res;
00307 
00308    res = (int) *input + *value;
00309    if (res > 32767)
00310       *input = 32767;
00311    else if (res < -32767)
00312       *input = -32767;
00313    else
00314       *input = (short) res;
00315 }
00316 
00317 static force_inline void ast_slinear_saturated_subtract(short *input, short *value)
00318 {
00319    int res;
00320 
00321    res = (int) *input - *value;
00322    if (res > 32767)
00323       *input = 32767;
00324    else if (res < -32767)
00325       *input = -32767;
00326    else
00327       *input = (short) res;
00328 }
00329    
00330 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
00331 {
00332    int res;
00333 
00334    res = (int) *input * *value;
00335    if (res > 32767)
00336       *input = 32767;
00337    else if (res < -32767)
00338       *input = -32767;
00339    else
00340       *input = (short) res;
00341 }
00342 
00343 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
00344 {
00345    *input /= *value;
00346 }
00347 
00348 #ifdef localtime_r
00349 #undef localtime_r
00350 #endif
00351 #define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
00352 
00353 int ast_utils_init(void);
00354 int ast_wait_for_input(int fd, int ms);
00355 
00356 /*!
00357    \brief Try to write string, but wait no more than ms milliseconds
00358    before timing out.
00359 
00360    \note If you are calling ast_carefulwrite, it is assumed that you are calling
00361    it on a file descriptor that _DOES_ have NONBLOCK set.  This way,
00362    there is only one system call made to do a write, unless we actually
00363    have a need to wait.  This way, we get better performance.
00364 */
00365 int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
00366 
00367 /*!
00368  * \brief Write data to a file stream with a timeout
00369  *
00370  * \param f the file stream to write to
00371  * \param fd the file description to poll on to know when the file stream can
00372  *        be written to without blocking.
00373  * \param s the buffer to write from
00374  * \param len the number of bytes to write
00375  * \param timeoutms The maximum amount of time to block in this function trying
00376  *        to write, specified in milliseconds.
00377  *
00378  * \note This function assumes that the associated file stream has been set up
00379  *       as non-blocking.
00380  *
00381  * \retval 0 success
00382  * \retval -1 error
00383  */
00384 int ast_careful_fwrite(FILE *f, int fd, const char *s, size_t len, int timeoutms);
00385 
00386 /*
00387  * Thread management support (should be moved to lock.h or a different header)
00388  */
00389 
00390 #define AST_STACKSIZE (((sizeof(void *) * 8 * 8) - 16) * 1024)
00391 
00392 #if defined(LOW_MEMORY)
00393 #define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
00394 #else
00395 #define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
00396 #endif
00397 
00398 void ast_register_thread(char *name);
00399 void ast_unregister_thread(void *id);
00400 
00401 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
00402               void *data, size_t stacksize, const char *file, const char *caller,
00403               int line, const char *start_fn);
00404 
00405 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void*(*start_routine)(void *),
00406              void *data, size_t stacksize, const char *file, const char *caller,
00407              int line, const char *start_fn);
00408 
00409 #define ast_pthread_create(a, b, c, d)             \
00410    ast_pthread_create_stack(a, b, c, d,         \
00411       0, __FILE__, __FUNCTION__, __LINE__, #c)
00412 
00413 #define ast_pthread_create_detached(a, b, c, d)       \
00414    ast_pthread_create_detached_stack(a, b, c, d,      \
00415       0, __FILE__, __FUNCTION__, __LINE__, #c)
00416 
00417 #define ast_pthread_create_background(a, b, c, d)     \
00418    ast_pthread_create_stack(a, b, c, d,         \
00419       AST_BACKGROUND_STACKSIZE,        \
00420       __FILE__, __FUNCTION__, __LINE__, #c)
00421 
00422 #define ast_pthread_create_detached_background(a, b, c, d)  \
00423    ast_pthread_create_detached_stack(a, b, c, d,      \
00424       AST_BACKGROUND_STACKSIZE,        \
00425       __FILE__, __FUNCTION__, __LINE__, #c)
00426 
00427 /* End of thread management support */
00428 
00429 /*!
00430    \brief Process a string to find and replace characters
00431    \param start The string to analyze
00432    \param find The character to find
00433    \param replace_with The character that will replace the one we are looking for
00434 */
00435 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
00436 
00437 long int ast_random(void);
00438 
00439 
00440 /*! 
00441  * \brief free() wrapper
00442  *
00443  * ast_free_ptr should be used when a function pointer for free() needs to be passed
00444  * as the argument to a function. Otherwise, astmm will cause seg faults.
00445  */
00446 #ifdef __AST_DEBUG_MALLOC
00447 static void ast_free_ptr(void *ptr) attribute_unused;
00448 static void ast_free_ptr(void *ptr)
00449 {
00450    ast_free(ptr);
00451 }
00452 #else
00453 #define ast_free free
00454 #define ast_free_ptr ast_free
00455 #endif
00456 
00457 #ifndef __AST_DEBUG_MALLOC
00458 
00459 #define MALLOC_FAILURE_MSG \
00460    ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
00461 /*!
00462  * \brief A wrapper for malloc()
00463  *
00464  * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
00465  * message in the case that the allocation fails.
00466  *
00467  * The argument and return value are the same as malloc()
00468  */
00469 #define ast_malloc(len) \
00470    _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00471 
00472 AST_INLINE_API(
00473 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
00474 {
00475    void *p;
00476 
00477    if (!(p = malloc(len)))
00478       MALLOC_FAILURE_MSG;
00479 
00480    return p;
00481 }
00482 )
00483 
00484 /*!
00485  * \brief A wrapper for calloc()
00486  *
00487  * ast_calloc() is a wrapper for calloc() 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 calloc()
00491  */
00492 #define ast_calloc(num, len) \
00493    _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00494 
00495 AST_INLINE_API(
00496 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
00497 {
00498    void *p;
00499 
00500    if (!(p = calloc(num, len)))
00501       MALLOC_FAILURE_MSG;
00502 
00503    return p;
00504 }
00505 )
00506 
00507 /*!
00508  * \brief A wrapper for calloc() for use in cache pools
00509  *
00510  * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
00511  * message in the case that the allocation fails. When memory debugging is in use,
00512  * the memory allocated by this function will be marked as 'cache' so it can be
00513  * distinguished from normal memory allocations.
00514  *
00515  * The arguments and return value are the same as calloc()
00516  */
00517 #define ast_calloc_cache(num, len) \
00518    _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00519 
00520 /*!
00521  * \brief A wrapper for realloc()
00522  *
00523  * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
00524  * message in the case that the allocation fails.
00525  *
00526  * The arguments and return value are the same as realloc()
00527  */
00528 #define ast_realloc(p, len) \
00529    _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00530 
00531 AST_INLINE_API(
00532 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
00533 {
00534    void *newp;
00535 
00536    if (!(newp = realloc(p, len)))
00537       MALLOC_FAILURE_MSG;
00538 
00539    return newp;
00540 }
00541 )
00542 
00543 /*!
00544  * \brief A wrapper for strdup()
00545  *
00546  * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
00547  * message in the case that the allocation fails.
00548  *
00549  * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
00550  * argument is provided, ast_strdup will return NULL without generating any
00551  * kind of error log message.
00552  *
00553  * The argument and return value are the same as strdup()
00554  */
00555 #define ast_strdup(str) \
00556    _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00557 
00558 AST_INLINE_API(
00559 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
00560 {
00561    char *newstr = NULL;
00562 
00563    if (str) {
00564       if (!(newstr = strdup(str)))
00565          MALLOC_FAILURE_MSG;
00566    }
00567 
00568    return newstr;
00569 }
00570 )
00571 
00572 /*!
00573  * \brief A wrapper for strndup()
00574  *
00575  * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
00576  * message in the case that the allocation fails.
00577  *
00578  * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
00579  * string to duplicate. If a NULL argument is provided, ast_strdup will return  
00580  * NULL without generating any kind of error log message.
00581  *
00582  * The arguments and return value are the same as strndup()
00583  */
00584 #define ast_strndup(str, len) \
00585    _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00586 
00587 AST_INLINE_API(
00588 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
00589 {
00590    char *newstr = NULL;
00591 
00592    if (str) {
00593       if (!(newstr = strndup(str, len)))
00594          MALLOC_FAILURE_MSG;
00595    }
00596 
00597    return newstr;
00598 }
00599 )
00600 
00601 /*!
00602  * \brief A wrapper for asprintf()
00603  *
00604  * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
00605  * message in the case that the allocation fails.
00606  *
00607  * The arguments and return value are the same as asprintf()
00608  */
00609 #define ast_asprintf(ret, fmt, ...) \
00610    _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
00611 
00612 int __attribute__((format(printf, 5, 6)))
00613    _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...);
00614 
00615 /*!
00616  * \brief A wrapper for vasprintf()
00617  *
00618  * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
00619  * message in the case that the allocation fails.
00620  *
00621  * The arguments and return value are the same as vasprintf()
00622  */
00623 #define ast_vasprintf(ret, fmt, ap) \
00624    _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
00625 
00626 AST_INLINE_API(
00627 __attribute__((format(printf, 5, 0)))
00628 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
00629 {
00630    int res;
00631 
00632    if ((res = vasprintf(ret, fmt, ap)) == -1)
00633       MALLOC_FAILURE_MSG;
00634 
00635    return res;
00636 }
00637 )
00638 
00639 #endif /* AST_DEBUG_MALLOC */
00640 
00641 #if !defined(ast_strdupa) && defined(__GNUC__)
00642 /*!
00643   \brief duplicate a string in memory from the stack
00644   \param s The string to duplicate
00645 
00646   This macro will duplicate the given string.  It returns a pointer to the stack
00647   allocatted memory for the new string.
00648 */
00649 #define ast_strdupa(s)                                                    \
00650    (__extension__                                                    \
00651    ({                                                                \
00652       const char *__old = (s);                                  \
00653       size_t __len = strlen(__old) + 1;                         \
00654       char *__new = __builtin_alloca(__len);                    \
00655       memcpy (__new, __old, __len);                             \
00656       __new;                                                    \
00657    }))
00658 #endif
00659 
00660 /*!
00661   \brief Disable PMTU discovery on a socket
00662   \param sock The socket to manipulate
00663   \return Nothing
00664 
00665   On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
00666   bit set. This is supposedly done to allow the application to do PMTU
00667   discovery, but Asterisk does not do this.
00668 
00669   Because of this, UDP packets sent by Asterisk that are larger than the MTU
00670   of any hop in the path will be lost. This function can be called on a socket
00671   to ensure that the DF bit will not be set.
00672  */
00673 void ast_enable_packet_fragmentation(int sock);
00674 
00675 /*!
00676   \brief Recursively create directory path
00677   \param path The directory path to create
00678   \param mode The permissions with which to try to create the directory
00679   \return 0 on success or an error code otherwise
00680 
00681   Creates a directory path, creating parent directories as needed.
00682  */
00683 int ast_mkdir(const char *path, int mode);
00684 
00685 #define ARRAY_LEN(a) (size_t) (sizeof(a) / sizeof(0[a]))
00686 
00687 
00688 /* Definition for Digest authorization */
00689 struct ast_http_digest {
00690    AST_DECLARE_STRING_FIELDS(
00691       AST_STRING_FIELD(username);
00692       AST_STRING_FIELD(nonce);
00693       AST_STRING_FIELD(uri);
00694       AST_STRING_FIELD(realm);
00695       AST_STRING_FIELD(domain);
00696       AST_STRING_FIELD(response);
00697       AST_STRING_FIELD(cnonce);
00698       AST_STRING_FIELD(opaque);
00699       AST_STRING_FIELD(nc);
00700    );
00701    int qop;    /* Flag set to 1, if we send/recv qop="quth" */
00702 };
00703 
00704 /*!
00705  *\brief Parse digest authorization header.
00706  *\return Returns -1 if we have no auth or something wrong with digest.
00707  *\note This function may be used for Digest request and responce header.
00708  * request arg is set to nonzero, if we parse Digest Request.
00709  * pedantic arg can be set to nonzero if we need to do addition Digest check.
00710  */
00711 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic);
00712 
00713 
00714 #ifdef AST_DEVMODE
00715 #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00716 static void force_inline _ast_assert(int condition, const char *condition_str, 
00717    const char *file, int line, const char *function)
00718 {
00719    if (__builtin_expect(!condition, 1)) {
00720       /* Attempt to put it into the logger, but hope that at least someone saw the
00721        * message on stderr ... */
00722       ast_log(__LOG_ERROR, file, line, function, "FRACK!, Failed assertion %s (%d)\n",
00723          condition_str, condition);
00724       fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
00725          condition_str, condition, line, function, file);
00726       /* Give the logger a chance to get the message out, just in case we abort(), or
00727        * Asterisk crashes due to whatever problem just happened after we exit ast_assert(). */
00728       usleep(1);
00729 #ifdef DO_CRASH
00730       abort();
00731       /* Just in case abort() doesn't work or something else super silly,
00732        * and for Qwell's amusement. */
00733       *((int*)0)=0;
00734 #endif
00735    }
00736 }
00737 #else
00738 #define ast_assert(a)
00739 #endif
00740 
00741 #include "asterisk/strings.h"
00742 
00743 /*!
00744  * \brief Return the number of bytes used in the alignment of type.
00745  * \param type
00746  * \return The number of bytes required for alignment.
00747  *
00748  * This is really just __alignof__(), but tucked away in this header so we
00749  * don't have to look at the nasty underscores in the source.
00750  */
00751 #define ast_alignof(type) __alignof__(type)
00752 
00753 /*!
00754  * \brief Increase offset so it is a multiple of the required alignment of type.
00755  * \param offset The value that should be increased.
00756  * \param type The data type that offset should be aligned to.
00757  * \return The smallest multiple of alignof(type) larger than or equal to offset.
00758  * \see ast_make_room_for()
00759  *
00760  * Many systems prefer integers to be stored on aligned on memory locations.
00761  * This macro will increase an offset so a value of the supplied type can be
00762  * safely be stored on such a memory location.
00763  *
00764  * Examples:
00765  * ast_align_for(0x17, int64_t) ==> 0x18
00766  * ast_align_for(0x18, int64_t) ==> 0x18
00767  * ast_align_for(0x19, int64_t) ==> 0x20
00768  *
00769  * Don't mind the ugliness, the compiler will optimize it.
00770  */
00771 #define ast_align_for(offset, type) (((offset + __alignof__(type) - 1) / __alignof__(type)) * __alignof__(type))
00772 
00773 /*!
00774  * \brief Increase offset by the required alignment of type and make sure it is
00775  *        a multiple of said alignment.
00776  * \param offset The value that should be increased.
00777  * \param type The data type that room should be reserved for.
00778  * \return The smallest multiple of alignof(type) larger than or equal to offset
00779  *         plus alignof(type).
00780  * \see ast_align_for()
00781  *
00782  * A use case for this is when prepending length fields of type int to a buffer.
00783  * If you keep the offset a multiple of the alignment of the integer type,
00784  * a next block of length+buffer will have the length field automatically
00785  * aligned.
00786  *
00787  * Examples:
00788  * ast_make_room_for(0x17, int64_t) ==> 0x20
00789  * ast_make_room_for(0x18, int64_t) ==> 0x20
00790  * ast_make_room_for(0x19, int64_t) ==> 0x28
00791  *
00792  * Don't mind the ugliness, the compiler will optimize it.
00793  */
00794 #define ast_make_room_for(offset, type) (((offset + (2 * __alignof__(type) - 1)) / __alignof__(type)) * __alignof__(type))
00795 
00796 /*!
00797  * \brief An Entity ID is essentially a MAC address, brief and unique 
00798  */
00799 struct ast_eid {
00800    unsigned char eid[6];
00801 } __attribute__((__packed__));
00802 
00803 /*!
00804  * \brief Global EID
00805  *
00806  * This is set in asterisk.conf, or determined automatically by taking the mac
00807  * address of an Ethernet interface on the system.
00808  */
00809 extern struct ast_eid ast_eid_default;
00810 
00811 /*!
00812  * \brief Fill in an ast_eid with the default eid of this machine
00813  * \since 1.6.1
00814  */
00815 void ast_set_default_eid(struct ast_eid *eid);
00816 
00817 /*!
00818  * /brief Convert an EID to a string
00819  * \since 1.6.1
00820  */
00821 char *ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid);
00822 
00823 /*!
00824  * \brief Convert a string into an EID
00825  *
00826  * This function expects an EID in the format:
00827  *    00:11:22:33:44:55
00828  *
00829  * \return 0 success, non-zero failure
00830  * \since 1.6.1
00831  */
00832 int ast_str_to_eid(struct ast_eid *eid, const char *s);
00833 
00834 /*!
00835  * \brief Compare two EIDs
00836  *
00837  * \return 0 if the two are the same, non-zero otherwise
00838  * \since 1.6.1
00839  */
00840 int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
00841 
00842 /*!
00843  * \brief Get current thread ID
00844  * \param None
00845  * \return the ID if platform is supported, else -1
00846  */
00847 int ast_get_tid(void);
00848 
00849 /*!\brief Resolve a binary to a full pathname
00850  * \param binary Name of the executable to resolve
00851  * \param fullpath Buffer to hold the complete pathname
00852  * \param fullpath_size Size of \a fullpath
00853  * \retval NULL \a binary was not found or the environment variable PATH is not set
00854  * \return \a fullpath
00855  */
00856 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size);
00857 
00858 #endif /* _ASTERISK_UTILS_H */

Generated on Sat Feb 11 06:33:25 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6