83d9e2185fb8b053c02c5c079b71483716b27582
[asterisk/asterisk.git] / include / asterisk / utils.h
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Utility functions
5  *
6  * Copyright (C) 2004 - 2005, Digium, Inc.
7  *
8  * This program is free software, distributed under the terms of
9  * the GNU General Public License
10  */
11
12 #ifndef _ASTERISK_UTILS_H
13 #define _ASTERISK_UTILS_H
14
15 #ifdef SOLARIS
16 #include <solaris-compat/compat.h>
17 #endif
18
19 #include <netinet/in.h>
20 #include <arpa/inet.h>  /* we want to override inet_ntoa */
21 #include <netdb.h>
22 #include <limits.h>
23
24 #include "asterisk/lock.h"
25 #include "asterisk/time.h"
26 #include "asterisk/strings.h"
27
28 /* Note:
29    It is very important to use only unsigned variables to hold
30    bit flags, as otherwise you can fall prey to the compiler's
31    sign-extension antics if you try to use the top two bits in
32    your variable.
33
34    The flag macros below use a set of compiler tricks to verify
35    that the caller is using an "unsigned int" variable to hold
36    the flags, and nothing else. If the caller uses any other
37    type of variable, a warning message similar to this:
38
39    warning: comparison of distinct pointer types lacks cast
40
41    will be generated.
42
43    The "dummy" variable below is used to make these comparisons.
44
45    Also note that at -O2 or above, this type-safety checking
46    does _not_ produce any additional object code at all.
47 */
48
49 extern unsigned int __unsigned_int_flags_dummy;
50
51 #define ast_test_flag(p,flag)           ({ \
52                                         typeof ((p)->flags) __p = (p)->flags; \
53                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
54                                         (void) (&__p == &__x); \
55                                         ((p)->flags & (flag)); \
56                                         })
57
58 #define ast_set_flag(p,flag)            do { \
59                                         typeof ((p)->flags) __p = (p)->flags; \
60                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
61                                         (void) (&__p == &__x); \
62                                         ((p)->flags |= (flag)); \
63                                         } while(0)
64
65 #define ast_clear_flag(p,flag)          do { \
66                                         typeof ((p)->flags) __p = (p)->flags; \
67                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
68                                         (void) (&__p == &__x); \
69                                         ((p)->flags &= ~(flag)); \
70                                         } while(0)
71
72 #define ast_copy_flags(dest,src,flagz)  do { \
73                                         typeof ((dest)->flags) __d = (dest)->flags; \
74                                         typeof ((src)->flags) __s = (src)->flags; \
75                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
76                                         (void) (&__d == &__x); \
77                                         (void) (&__s == &__x); \
78                                         (dest)->flags &= ~(flagz); \
79                                         (dest)->flags |= ((src)->flags & (flagz)); \
80                                         } while (0)
81
82 #define ast_set2_flag(p,value,flag)     do { \
83                                         typeof ((p)->flags) __p = (p)->flags; \
84                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
85                                         (void) (&__p == &__x); \
86                                         if (value) \
87                                                 (p)->flags |= (flag); \
88                                         else \
89                                                 (p)->flags &= ~(flag); \
90                                         } while (0)
91
92 /* Non-type checking variations for non-unsigned int flags.  You
93    should only use non-unsigned int flags where required by 
94    protocol etc and if you know what you're doing :)  */
95 #define ast_test_flag_nonstd(p,flag)            ({ \
96                                         ((p)->flags & (flag)); \
97                                         })
98
99 #define ast_set_flag_nonstd(p,flag)             do { \
100                                         ((p)->flags |= (flag)); \
101                                         } while(0)
102
103 #define ast_clear_flag_nonstd(p,flag)           do { \
104                                         ((p)->flags &= ~(flag)); \
105                                         } while(0)
106
107 #define ast_copy_flags_nonstd(dest,src,flagz)   do { \
108                                         (dest)->flags &= ~(flagz); \
109                                         (dest)->flags |= ((src)->flags & (flagz)); \
110                                         } while (0)
111
112 #define ast_set2_flag_nonstd(p,value,flag)      do { \
113                                         if (value) \
114                                                 (p)->flags |= (flag); \
115                                         else \
116                                                 (p)->flags &= ~(flag); \
117                                         } while (0)
118
119 #define AST_FLAGS_ALL UINT_MAX
120
121 struct ast_flags {
122         unsigned int flags;
123 };
124
125 struct ast_hostent {
126         struct hostent hp;
127         char buf[1024];
128 };
129
130 extern struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
131
132 /* ast_md5_hash 
133         \brief Produces MD5 hash based on input string */
134 extern void ast_md5_hash(char *output, char *input);
135
136 extern int ast_base64encode(char *dst, unsigned char *src, int srclen, int max);
137 extern int ast_base64decode(unsigned char *dst, char *src, int max);
138
139 /*! ast_uri_encode
140         \brief Turn text string to URI-encoded %XX version 
141         At this point, we're converting from ISO-8859-x (8-bit), not UTF8
142         as in the SIP protocol spec 
143         If doreserved == 1 we will convert reserved characters also.
144         RFC 2396, section 2.4
145         outbuf needs to have more memory allocated than the instring
146         to have room for the expansion. Every char that is converted
147         is replaced by three ASCII characters.
148         \param string   String to be converted
149         \param outbuf   Resulting encoded string
150         \param buflen   Size of output buffer
151         \param doreserved       Convert reserved characters
152 */
153
154 char *ast_uri_encode(char *string, char *outbuf, int buflen, int doreserved);
155
156 /*!     \brief Decode URI, URN, URL (overwrite string)
157         \param s        String to be decoded 
158  */
159 void ast_uri_decode(char *s);
160         
161
162 extern int test_for_thread_safety(void);
163
164 extern const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia);
165
166 #ifdef inet_ntoa
167 #undef inet_ntoa
168 #endif
169 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
170
171 extern int ast_utils_init(void);
172 extern int ast_wait_for_input(int fd, int ms);
173
174 /*! Compares the source address and port of two sockaddr_in */
175 static inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
176 {
177         return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) 
178                 || (sin1->sin_port != sin2->sin_port));
179 }
180
181 #define AST_STACKSIZE 256 * 1024
182 #define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0)
183 extern int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize);
184
185 #endif /* _ASTERISK_UTILS_H */