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

Generated on Thu Oct 11 06:47:22 2012 for Asterisk - the Open Source PBX by  doxygen 1.5.6