Fri Jul 3 06:26:43 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/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 /*!
00226  * \brief Encode data in base64
00227  * \param dst the destination buffer
00228  * \param src the source data to be encoded
00229  * \param srclen the number of bytes present in the source buffer
00230  * \param max the maximum number of bytes to write into the destination
00231  *        buffer, *including* the terminating NULL character.
00232  */
00233 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
00234 
00235 /*!
00236  * \brief Decode data from base64
00237  * \param dst the destination buffer
00238  * \param src the source buffer
00239  * \param max The maximum number of bytes to write into the destination
00240  *            buffer.  Note that this function will not ensure that the
00241  *            destination buffer is NULL terminated.  So, in general,
00242  *            this parameter should be sizeof(dst) - 1.
00243  */
00244 int ast_base64decode(unsigned char *dst, const char *src, int max);
00245 
00246 /*!  \brief Turn text string to URI-encoded %XX version 
00247 
00248 \note    At this point, we're converting from ISO-8859-x (8-bit), not UTF8
00249    as in the SIP protocol spec 
00250    If doreserved == 1 we will convert reserved characters also.
00251    RFC 2396, section 2.4
00252    outbuf needs to have more memory allocated than the instring
00253    to have room for the expansion. Every char that is converted
00254    is replaced by three ASCII characters.
00255    \param string  String to be converted
00256    \param outbuf  Resulting encoded string
00257    \param buflen  Size of output buffer
00258    \param doreserved Convert reserved characters
00259 */
00260 
00261 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved);
00262 
00263 /*!   \brief Decode URI, URN, URL (overwrite string)
00264    \param s String to be decoded 
00265  */
00266 void ast_uri_decode(char *s);
00267 
00268 static force_inline void ast_slinear_saturated_add(short *input, short *value)
00269 {
00270    int res;
00271 
00272    res = (int) *input + *value;
00273    if (res > 32767)
00274       *input = 32767;
00275    else if (res < -32767)
00276       *input = -32767;
00277    else
00278       *input = (short) res;
00279 }
00280 
00281 static force_inline void ast_slinear_saturated_subtract(short *input, short *value)
00282 {
00283    int res;
00284 
00285    res = (int) *input - *value;
00286    if (res > 32767)
00287       *input = 32767;
00288    else if (res < -32767)
00289       *input = -32767;
00290    else
00291       *input = (short) res;
00292 }
00293    
00294 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
00295 {
00296    int res;
00297 
00298    res = (int) *input * *value;
00299    if (res > 32767)
00300       *input = 32767;
00301    else if (res < -32767)
00302       *input = -32767;
00303    else
00304       *input = (short) res;
00305 }
00306 
00307 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
00308 {
00309    *input /= *value;
00310 }
00311 
00312 #ifdef localtime_r
00313 #undef localtime_r
00314 #endif
00315 #define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
00316 
00317 int ast_utils_init(void);
00318 int ast_wait_for_input(int fd, int ms);
00319 
00320 /*!
00321    \brief Try to write string, but wait no more than ms milliseconds
00322    before timing out.
00323 
00324    \note If you are calling ast_carefulwrite, it is assumed that you are calling
00325    it on a file descriptor that _DOES_ have NONBLOCK set.  This way,
00326    there is only one system call made to do a write, unless we actually
00327    have a need to wait.  This way, we get better performance.
00328 */
00329 int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
00330 
00331 /*!
00332  * \brief Write data to a file stream with a timeout
00333  *
00334  * \param f the file stream to write to
00335  * \param fd the file description to poll on to know when the file stream can
00336  *        be written to without blocking.
00337  * \param s the buffer to write from
00338  * \param len the number of bytes to write
00339  * \param timeoutms The maximum amount of time to block in this function trying
00340  *        to write, specified in milliseconds.
00341  *
00342  * \note This function assumes that the associated file stream has been set up
00343  *       as non-blocking.
00344  *
00345  * \retval 0 success
00346  * \retval -1 error
00347  */
00348 int ast_careful_fwrite(FILE *f, int fd, const char *s, size_t len, int timeoutms);
00349 
00350 /*
00351  * Thread management support (should be moved to lock.h or a different header)
00352  */
00353 
00354 #define AST_STACKSIZE (((sizeof(void *) * 8 * 8) - 16) * 1024)
00355 
00356 #if defined(LOW_MEMORY)
00357 #define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
00358 #else
00359 #define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
00360 #endif
00361 
00362 void ast_register_thread(char *name);
00363 void ast_unregister_thread(void *id);
00364 
00365 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
00366               void *data, size_t stacksize, const char *file, const char *caller,
00367               int line, const char *start_fn);
00368 
00369 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void*(*start_routine)(void *),
00370              void *data, size_t stacksize, const char *file, const char *caller,
00371              int line, const char *start_fn);
00372 
00373 #define ast_pthread_create(a, b, c, d)             \
00374    ast_pthread_create_stack(a, b, c, d,         \
00375       0, __FILE__, __FUNCTION__, __LINE__, #c)
00376 
00377 #define ast_pthread_create_detached(a, b, c, d)       \
00378    ast_pthread_create_detached_stack(a, b, c, d,      \
00379       0, __FILE__, __FUNCTION__, __LINE__, #c)
00380 
00381 #define ast_pthread_create_background(a, b, c, d)     \
00382    ast_pthread_create_stack(a, b, c, d,         \
00383       AST_BACKGROUND_STACKSIZE,        \
00384       __FILE__, __FUNCTION__, __LINE__, #c)
00385 
00386 #define ast_pthread_create_detached_background(a, b, c, d)  \
00387    ast_pthread_create_detached_stack(a, b, c, d,      \
00388       AST_BACKGROUND_STACKSIZE,        \
00389       __FILE__, __FUNCTION__, __LINE__, #c)
00390 
00391 /* End of thread management support */
00392 
00393 /*!
00394    \brief Process a string to find and replace characters
00395    \param start The string to analyze
00396    \param find The character to find
00397    \param replace_with The character that will replace the one we are looking for
00398 */
00399 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
00400 
00401 long int ast_random(void);
00402 
00403 
00404 /*! 
00405  * \brief free() wrapper
00406  *
00407  * ast_free_ptr should be used when a function pointer for free() needs to be passed
00408  * as the argument to a function. Otherwise, astmm will cause seg faults.
00409  */
00410 #ifdef __AST_DEBUG_MALLOC
00411 static void ast_free_ptr(void *ptr) attribute_unused;
00412 static void ast_free_ptr(void *ptr)
00413 {
00414    ast_free(ptr);
00415 }
00416 #else
00417 #define ast_free free
00418 #define ast_free_ptr ast_free
00419 #endif
00420 
00421 #ifndef __AST_DEBUG_MALLOC
00422 
00423 #define MALLOC_FAILURE_MSG \
00424    ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
00425 /*!
00426  * \brief A wrapper for malloc()
00427  *
00428  * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
00429  * message in the case that the allocation fails.
00430  *
00431  * The argument and return value are the same as malloc()
00432  */
00433 #define ast_malloc(len) \
00434    _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00435 
00436 AST_INLINE_API(
00437 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
00438 {
00439    void *p;
00440 
00441    if (!(p = malloc(len)))
00442       MALLOC_FAILURE_MSG;
00443 
00444    return p;
00445 }
00446 )
00447 
00448 /*!
00449  * \brief A wrapper for calloc()
00450  *
00451  * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
00452  * message in the case that the allocation fails.
00453  *
00454  * The arguments and return value are the same as calloc()
00455  */
00456 #define ast_calloc(num, len) \
00457    _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00458 
00459 AST_INLINE_API(
00460 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
00461 {
00462    void *p;
00463 
00464    if (!(p = calloc(num, len)))
00465       MALLOC_FAILURE_MSG;
00466 
00467    return p;
00468 }
00469 )
00470 
00471 /*!
00472  * \brief A wrapper for calloc() for use in cache pools
00473  *
00474  * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
00475  * message in the case that the allocation fails. When memory debugging is in use,
00476  * the memory allocated by this function will be marked as 'cache' so it can be
00477  * distinguished from normal memory allocations.
00478  *
00479  * The arguments and return value are the same as calloc()
00480  */
00481 #define ast_calloc_cache(num, len) \
00482    _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00483 
00484 /*!
00485  * \brief A wrapper for realloc()
00486  *
00487  * ast_realloc() is a wrapper for realloc() 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 realloc()
00491  */
00492 #define ast_realloc(p, len) \
00493    _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00494 
00495 AST_INLINE_API(
00496 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
00497 {
00498    void *newp;
00499 
00500    if (!(newp = realloc(p, len)))
00501       MALLOC_FAILURE_MSG;
00502 
00503    return newp;
00504 }
00505 )
00506 
00507 /*!
00508  * \brief A wrapper for strdup()
00509  *
00510  * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
00511  * message in the case that the allocation fails.
00512  *
00513  * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
00514  * argument is provided, ast_strdup will return NULL without generating any
00515  * kind of error log message.
00516  *
00517  * The argument and return value are the same as strdup()
00518  */
00519 #define ast_strdup(str) \
00520    _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00521 
00522 AST_INLINE_API(
00523 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
00524 {
00525    char *newstr = NULL;
00526 
00527    if (str) {
00528       if (!(newstr = strdup(str)))
00529          MALLOC_FAILURE_MSG;
00530    }
00531 
00532    return newstr;
00533 }
00534 )
00535 
00536 /*!
00537  * \brief A wrapper for strndup()
00538  *
00539  * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
00540  * message in the case that the allocation fails.
00541  *
00542  * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
00543  * string to duplicate. If a NULL argument is provided, ast_strdup will return  
00544  * NULL without generating any kind of error log message.
00545  *
00546  * The arguments and return value are the same as strndup()
00547  */
00548 #define ast_strndup(str, len) \
00549    _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00550 
00551 AST_INLINE_API(
00552 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
00553 {
00554    char *newstr = NULL;
00555 
00556    if (str) {
00557       if (!(newstr = strndup(str, len)))
00558          MALLOC_FAILURE_MSG;
00559    }
00560 
00561    return newstr;
00562 }
00563 )
00564 
00565 /*!
00566  * \brief A wrapper for asprintf()
00567  *
00568  * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
00569  * message in the case that the allocation fails.
00570  *
00571  * The arguments and return value are the same as asprintf()
00572  */
00573 #define ast_asprintf(ret, fmt, ...) \
00574    _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
00575 
00576 int __attribute__((format(printf, 5, 6)))
00577    _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...);
00578 
00579 /*!
00580  * \brief A wrapper for vasprintf()
00581  *
00582  * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
00583  * message in the case that the allocation fails.
00584  *
00585  * The arguments and return value are the same as vasprintf()
00586  */
00587 #define ast_vasprintf(ret, fmt, ap) \
00588    _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
00589 
00590 AST_INLINE_API(
00591 __attribute__((format(printf, 5, 0)))
00592 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
00593 {
00594    int res;
00595 
00596    if ((res = vasprintf(ret, fmt, ap)) == -1)
00597       MALLOC_FAILURE_MSG;
00598 
00599    return res;
00600 }
00601 )
00602 
00603 #endif /* AST_DEBUG_MALLOC */
00604 
00605 #if !defined(ast_strdupa) && defined(__GNUC__)
00606 /*!
00607   \brief duplicate a string in memory from the stack
00608   \param s The string to duplicate
00609 
00610   This macro will duplicate the given string.  It returns a pointer to the stack
00611   allocatted memory for the new string.
00612 */
00613 #define ast_strdupa(s)                                                    \
00614    (__extension__                                                    \
00615    ({                                                                \
00616       const char *__old = (s);                                  \
00617       size_t __len = strlen(__old) + 1;                         \
00618       char *__new = __builtin_alloca(__len);                    \
00619       memcpy (__new, __old, __len);                             \
00620       __new;                                                    \
00621    }))
00622 #endif
00623 
00624 /*!
00625   \brief Disable PMTU discovery on a socket
00626   \param sock The socket to manipulate
00627   \return Nothing
00628 
00629   On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
00630   bit set. This is supposedly done to allow the application to do PMTU
00631   discovery, but Asterisk does not do this.
00632 
00633   Because of this, UDP packets sent by Asterisk that are larger than the MTU
00634   of any hop in the path will be lost. This function can be called on a socket
00635   to ensure that the DF bit will not be set.
00636  */
00637 void ast_enable_packet_fragmentation(int sock);
00638 
00639 /*!
00640   \brief Recursively create directory path
00641   \param path The directory path to create
00642   \param mode The permissions with which to try to create the directory
00643   \return 0 on success or an error code otherwise
00644 
00645   Creates a directory path, creating parent directories as needed.
00646  */
00647 int ast_mkdir(const char *path, int mode);
00648 
00649 #define ARRAY_LEN(a) (sizeof(a) / sizeof(0[a]))
00650 
00651 
00652 /* Definition for Digest authorization */
00653 struct ast_http_digest {
00654    AST_DECLARE_STRING_FIELDS(
00655       AST_STRING_FIELD(username);
00656       AST_STRING_FIELD(nonce);
00657       AST_STRING_FIELD(uri);
00658       AST_STRING_FIELD(realm);
00659       AST_STRING_FIELD(domain);
00660       AST_STRING_FIELD(response);
00661       AST_STRING_FIELD(cnonce);
00662       AST_STRING_FIELD(opaque);
00663       AST_STRING_FIELD(nc);
00664    );
00665    int qop;    /* Flag set to 1, if we send/recv qop="quth" */
00666 };
00667 
00668 /*!
00669  *\brief Parse digest authorization header.
00670  *\return Returns -1 if we have no auth or something wrong with digest.
00671  *\note This function may be used for Digest request and responce header.
00672  * request arg is set to nonzero, if we parse Digest Request.
00673  * pedantic arg can be set to nonzero if we need to do addition Digest check.
00674  */
00675 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic);
00676 
00677 
00678 #ifdef AST_DEVMODE
00679 #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00680 static void force_inline _ast_assert(int condition, const char *condition_str, 
00681    const char *file, int line, const char *function)
00682 {
00683    if (__builtin_expect(!condition, 1)) {
00684       /* Attempt to put it into the logger, but hope that at least someone saw the
00685        * message on stderr ... */
00686       ast_log(__LOG_ERROR, file, line, function, "FRACK!, Failed assertion %s (%d)\n",
00687          condition_str, condition);
00688       fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
00689          condition_str, condition, line, function, file);
00690       /* Give the logger a chance to get the message out, just in case we abort(), or
00691        * Asterisk crashes due to whatever problem just happened after we exit ast_assert(). */
00692       usleep(1);
00693 #ifdef DO_CRASH
00694       abort();
00695       /* Just in case abort() doesn't work or something else super silly,
00696        * and for Qwell's amusement. */
00697       *((int*)0)=0;
00698 #endif
00699    }
00700 }
00701 #else
00702 #define ast_assert(a)
00703 #endif
00704 
00705 #include "asterisk/strings.h"
00706 
00707 /*!
00708  * \brief An Entity ID is essentially a MAC address, brief and unique 
00709  */
00710 struct ast_eid {
00711    unsigned char eid[6];
00712 } __attribute__((__packed__));
00713 
00714 /*!
00715  * \brief Global EID
00716  *
00717  * This is set in asterisk.conf, or determined automatically by taking the mac
00718  * address of an Ethernet interface on the system.
00719  */
00720 extern struct ast_eid ast_eid_default;
00721 
00722 /*!
00723  * \brief Fill in an ast_eid with the default eid of this machine
00724  * \since 1.6.1
00725  */
00726 void ast_set_default_eid(struct ast_eid *eid);
00727 
00728 /*!
00729  * /brief Convert an EID to a string
00730  * \since 1.6.1
00731  */
00732 char *ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid);
00733 
00734 /*!
00735  * \brief Convert a string into an EID
00736  *
00737  * This function expects an EID in the format:
00738  *    00:11:22:33:44:55
00739  *
00740  * \return 0 success, non-zero failure
00741  * \since 1.6.1
00742  */
00743 int ast_str_to_eid(struct ast_eid *eid, const char *s);
00744 
00745 /*!
00746  * \brief Compare two EIDs
00747  *
00748  * \return 0 if the two are the same, non-zero otherwise
00749  * \since 1.6.1
00750  */
00751 int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
00752 
00753 #endif /* _ASTERISK_UTILS_H */

Generated on Fri Jul 3 06:26:43 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.1