1d398fa1043f639c747a9212eabd979d8eb202cb
[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 /* ast_md5_hash: Produces MD5 hash based on input string */
132 extern void ast_md5_hash(char *output, char *input);
133 extern int ast_base64encode(char *dst, unsigned char *src, int srclen, int max);
134 extern int ast_base64decode(unsigned char *dst, char *src, int max);
135
136 extern int test_for_thread_safety(void);
137
138 extern const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia);
139
140 #ifdef inet_ntoa
141 #undef inet_ntoa
142 #endif
143 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
144
145 extern int ast_utils_init(void);
146 extern int ast_wait_for_input(int fd, int ms);
147
148 /*! Compares the source address and port of two sockaddr_in */
149 static inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
150 {
151         return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) 
152                 || (sin1->sin_port != sin2->sin_port));
153 }
154
155 #define AST_STACKSIZE 256 * 1024
156 #define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0)
157 extern int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize);
158
159 #endif /* _ASTERISK_UTILS_H */