Thu May 24 14:31:54 2007

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 - 2005, 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 <netinet/in.h>
00029 #include <arpa/inet.h>  /* we want to override inet_ntoa */
00030 #include <netdb.h>
00031 #include <limits.h>
00032 
00033 #include "asterisk/lock.h"
00034 #include "asterisk/time.h"
00035 #include "asterisk/strings.h"
00036 
00037 /*! \note
00038  \verbatim
00039    Note:
00040    It is very important to use only unsigned variables to hold
00041    bit flags, as otherwise you can fall prey to the compiler's
00042    sign-extension antics if you try to use the top two bits in
00043    your variable.
00044 
00045    The flag macros below use a set of compiler tricks to verify
00046    that the caller is using an "unsigned int" variable to hold
00047    the flags, and nothing else. If the caller uses any other
00048    type of variable, a warning message similar to this:
00049 
00050    warning: comparison of distinct pointer types lacks cast
00051    will be generated.
00052 
00053    The "dummy" variable below is used to make these comparisons.
00054 
00055    Also note that at -O2 or above, this type-safety checking
00056    does _not_ produce any additional object code at all.
00057  \endverbatim
00058 */
00059 
00060 extern unsigned int __unsigned_int_flags_dummy;
00061 
00062 #define ast_test_flag(p,flag)       ({ \
00063                typeof ((p)->flags) __p = (p)->flags; \
00064                typeof (__unsigned_int_flags_dummy) __x = 0; \
00065                (void) (&__p == &__x); \
00066                ((p)->flags & (flag)); \
00067                })
00068 
00069 #define ast_set_flag(p,flag)     do { \
00070                typeof ((p)->flags) __p = (p)->flags; \
00071                typeof (__unsigned_int_flags_dummy) __x = 0; \
00072                (void) (&__p == &__x); \
00073                ((p)->flags |= (flag)); \
00074                } while(0)
00075 
00076 #define ast_clear_flag(p,flag)      do { \
00077                typeof ((p)->flags) __p = (p)->flags; \
00078                typeof (__unsigned_int_flags_dummy) __x = 0; \
00079                (void) (&__p == &__x); \
00080                ((p)->flags &= ~(flag)); \
00081                } while(0)
00082 
00083 #define ast_copy_flags(dest,src,flagz) do { \
00084                typeof ((dest)->flags) __d = (dest)->flags; \
00085                typeof ((src)->flags) __s = (src)->flags; \
00086                typeof (__unsigned_int_flags_dummy) __x = 0; \
00087                (void) (&__d == &__x); \
00088                (void) (&__s == &__x); \
00089                (dest)->flags &= ~(flagz); \
00090                (dest)->flags |= ((src)->flags & (flagz)); \
00091                } while (0)
00092 
00093 #define ast_set2_flag(p,value,flag) do { \
00094                typeof ((p)->flags) __p = (p)->flags; \
00095                typeof (__unsigned_int_flags_dummy) __x = 0; \
00096                (void) (&__p == &__x); \
00097                if (value) \
00098                   (p)->flags |= (flag); \
00099                else \
00100                   (p)->flags &= ~(flag); \
00101                } while (0)
00102 
00103 /* Non-type checking variations for non-unsigned int flags.  You
00104    should only use non-unsigned int flags where required by 
00105    protocol etc and if you know what you're doing :)  */
00106 #define ast_test_flag_nonstd(p,flag)      ({ \
00107                ((p)->flags & (flag)); \
00108                })
00109 
00110 #define ast_set_flag_nonstd(p,flag)       do { \
00111                ((p)->flags |= (flag)); \
00112                } while(0)
00113 
00114 #define ast_clear_flag_nonstd(p,flag)     do { \
00115                ((p)->flags &= ~(flag)); \
00116                } while(0)
00117 
00118 #define ast_copy_flags_nonstd(dest,src,flagz)   do { \
00119                (dest)->flags &= ~(flagz); \
00120                (dest)->flags |= ((src)->flags & (flagz)); \
00121                } while (0)
00122 
00123 #define ast_set2_flag_nonstd(p,value,flag)   do { \
00124                if (value) \
00125                   (p)->flags |= (flag); \
00126                else \
00127                   (p)->flags &= ~(flag); \
00128                } while (0)
00129 
00130 #define AST_FLAGS_ALL UINT_MAX
00131 
00132 struct ast_flags {
00133    unsigned int flags;
00134 };
00135 
00136 struct ast_hostent {
00137    struct hostent hp;
00138    char buf[1024];
00139 };
00140 
00141 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
00142 
00143 /* ast_md5_hash 
00144    \brief Produces MD5 hash based on input string */
00145 void ast_md5_hash(char *output, char *input);
00146 
00147 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
00148 int ast_base64decode(unsigned char *dst, const char *src, int max);
00149 
00150 /*! ast_uri_encode
00151    \brief Turn text string to URI-encoded %XX version 
00152    At this point, we're converting from ISO-8859-x (8-bit), not UTF8
00153    as in the SIP protocol spec 
00154    If doreserved == 1 we will convert reserved characters also.
00155    RFC 2396, section 2.4
00156    outbuf needs to have more memory allocated than the instring
00157    to have room for the expansion. Every char that is converted
00158    is replaced by three ASCII characters.
00159    \param string  String to be converted
00160    \param outbuf  Resulting encoded string
00161    \param buflen  Size of output buffer
00162    \param doreserved Convert reserved characters
00163 */
00164 
00165 char *ast_uri_encode(char *string, char *outbuf, int buflen, int doreserved);
00166 
00167 /*!   \brief Decode URI, URN, URL (overwrite string)
00168    \param s String to be decoded 
00169  */
00170 void ast_uri_decode(char *s);
00171 
00172 static force_inline void ast_slinear_saturated_add(short *input, short *value)
00173 {
00174    int res;
00175 
00176    res = (int) *input + *value;
00177    if (res > 32767)
00178       *input = 32767;
00179    else if (res < -32767)
00180       *input = -32767;
00181    else
00182       *input = (short) res;
00183 }
00184    
00185 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
00186 {
00187    int res;
00188 
00189    res = (int) *input * *value;
00190    if (res > 32767)
00191       *input = 32767;
00192    else if (res < -32767)
00193       *input = -32767;
00194    else
00195       *input = (short) res;
00196 }
00197 
00198 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
00199 {
00200    *input /= *value;
00201 }
00202 
00203 int test_for_thread_safety(void);
00204 
00205 const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia);
00206 
00207 #ifdef inet_ntoa
00208 #undef inet_ntoa
00209 #endif
00210 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
00211 
00212 int ast_utils_init(void);
00213 int ast_wait_for_input(int fd, int ms);
00214 
00215 /*! Compares the source address and port of two sockaddr_in */
00216 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
00217 {
00218    return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) 
00219       || (sin1->sin_port != sin2->sin_port));
00220 }
00221 
00222 #define AST_STACKSIZE 256 * 1024
00223 #define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0)
00224 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize);
00225 
00226 /*!
00227    \brief Process a string to find and replace characters
00228    \param start The string to analyze
00229    \param find The character to find
00230    \param replace_with The character that will replace the one we are looking for
00231 */
00232 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
00233 
00234 #ifndef HAVE_GETLOADAVG
00235 int getloadavg(double *list, int nelem);
00236 #endif
00237 
00238 /*!
00239   \brief Disable PMTU discovery on a socket
00240   \param sock The socket to manipulate
00241   \return Nothing
00242 
00243   On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
00244   bit set. This is supposedly done to allow the application to do PMTU
00245   discovery, but Asterisk does not do this.
00246 
00247   Because of this, UDP packets sent by Asterisk that are larger than the MTU
00248   of any hop in the path will be lost. This function can be called on a socket
00249   to ensure that the DF bit will not be set.
00250  */
00251 void ast_enable_packet_fragmentation(int sock);
00252 
00253 #endif /* _ASTERISK_UTILS_H */

Generated on Thu May 24 14:31:54 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1