Bug 6322 - Implementation of SHA1 in Asterisk (plus dialplan function to use it)
[asterisk/asterisk.git] / include / asterisk / utils.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  * \brief Utility functions
21  */
22
23 #ifndef _ASTERISK_UTILS_H
24 #define _ASTERISK_UTILS_H
25
26 #include "asterisk/compat.h"
27
28 #include <stdlib.h>
29 #include <netinet/in.h>
30 #include <arpa/inet.h>  /* we want to override inet_ntoa */
31 #include <netdb.h>
32 #include <limits.h>
33
34 #include "asterisk/lock.h"
35 #include "asterisk/time.h"
36 #include "asterisk/strings.h"
37 #include "asterisk/logger.h"
38
39 /*! \note
40  \verbatim
41    Note:
42    It is very important to use only unsigned variables to hold
43    bit flags, as otherwise you can fall prey to the compiler's
44    sign-extension antics if you try to use the top two bits in
45    your variable.
46
47    The flag macros below use a set of compiler tricks to verify
48    that the caller is using an "unsigned int" variable to hold
49    the flags, and nothing else. If the caller uses any other
50    type of variable, a warning message similar to this:
51
52    warning: comparison of distinct pointer types lacks cast
53    will be generated.
54
55    The "dummy" variable below is used to make these comparisons.
56
57    Also note that at -O2 or above, this type-safety checking
58    does _not_ produce any additional object code at all.
59  \endverbatim
60 */
61
62 extern unsigned int __unsigned_int_flags_dummy;
63
64 #define ast_test_flag(p,flag)           ({ \
65                                         typeof ((p)->flags) __p = (p)->flags; \
66                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
67                                         (void) (&__p == &__x); \
68                                         ((p)->flags & (flag)); \
69                                         })
70
71 #define ast_set_flag(p,flag)            do { \
72                                         typeof ((p)->flags) __p = (p)->flags; \
73                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
74                                         (void) (&__p == &__x); \
75                                         ((p)->flags |= (flag)); \
76                                         } while(0)
77
78 #define ast_clear_flag(p,flag)          do { \
79                                         typeof ((p)->flags) __p = (p)->flags; \
80                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
81                                         (void) (&__p == &__x); \
82                                         ((p)->flags &= ~(flag)); \
83                                         } while(0)
84
85 #define ast_copy_flags(dest,src,flagz)  do { \
86                                         typeof ((dest)->flags) __d = (dest)->flags; \
87                                         typeof ((src)->flags) __s = (src)->flags; \
88                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
89                                         (void) (&__d == &__x); \
90                                         (void) (&__s == &__x); \
91                                         (dest)->flags &= ~(flagz); \
92                                         (dest)->flags |= ((src)->flags & (flagz)); \
93                                         } while (0)
94
95 #define ast_set2_flag(p,value,flag)     do { \
96                                         typeof ((p)->flags) __p = (p)->flags; \
97                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
98                                         (void) (&__p == &__x); \
99                                         if (value) \
100                                                 (p)->flags |= (flag); \
101                                         else \
102                                                 (p)->flags &= ~(flag); \
103                                         } while (0)
104
105 /* Non-type checking variations for non-unsigned int flags.  You
106    should only use non-unsigned int flags where required by 
107    protocol etc and if you know what you're doing :)  */
108 #define ast_test_flag_nonstd(p,flag)            ({ \
109                                         ((p)->flags & (flag)); \
110                                         })
111
112 #define ast_set_flag_nonstd(p,flag)             do { \
113                                         ((p)->flags |= (flag)); \
114                                         } while(0)
115
116 #define ast_clear_flag_nonstd(p,flag)           do { \
117                                         ((p)->flags &= ~(flag)); \
118                                         } while(0)
119
120 #define ast_copy_flags_nonstd(dest,src,flagz)   do { \
121                                         (dest)->flags &= ~(flagz); \
122                                         (dest)->flags |= ((src)->flags & (flagz)); \
123                                         } while (0)
124
125 #define ast_set2_flag_nonstd(p,value,flag)      do { \
126                                         if (value) \
127                                                 (p)->flags |= (flag); \
128                                         else \
129                                                 (p)->flags &= ~(flag); \
130                                         } while (0)
131
132 #define AST_FLAGS_ALL UINT_MAX
133
134 struct ast_flags {
135         unsigned int flags;
136 };
137
138 struct ast_hostent {
139         struct hostent hp;
140         char buf[1024];
141 };
142
143 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
144
145 /* ast_md5_hash 
146         \brief Produces MD5 hash based on input string */
147 void ast_md5_hash(char *output, char *input);
148 /* ast_sha1_hash
149         \brief Produces SHA1 hash based on input string */
150 void ast_sha1_hash(char *output, char *input);
151
152 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
153 int ast_base64decode(unsigned char *dst, const char *src, int max);
154
155 /*! ast_uri_encode
156         \brief Turn text string to URI-encoded %XX version 
157         At this point, we're converting from ISO-8859-x (8-bit), not UTF8
158         as in the SIP protocol spec 
159         If doreserved == 1 we will convert reserved characters also.
160         RFC 2396, section 2.4
161         outbuf needs to have more memory allocated than the instring
162         to have room for the expansion. Every char that is converted
163         is replaced by three ASCII characters.
164         \param string   String to be converted
165         \param outbuf   Resulting encoded string
166         \param buflen   Size of output buffer
167         \param doreserved       Convert reserved characters
168 */
169
170 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved);
171
172 /*!     \brief Decode URI, URN, URL (overwrite string)
173         \param s        String to be decoded 
174  */
175 void ast_uri_decode(char *s);
176
177 static force_inline void ast_slinear_saturated_add(short *input, short *value)
178 {
179         int res;
180
181         res = (int) *input + *value;
182         if (res > 32767)
183                 *input = 32767;
184         else if (res < -32767)
185                 *input = -32767;
186         else
187                 *input = (short) res;
188 }
189         
190 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
191 {
192         int res;
193
194         res = (int) *input * *value;
195         if (res > 32767)
196                 *input = 32767;
197         else if (res < -32767)
198                 *input = -32767;
199         else
200                 *input = (short) res;
201 }
202
203 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
204 {
205         *input /= *value;
206 }
207
208 int test_for_thread_safety(void);
209
210 const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia);
211
212 #ifdef inet_ntoa
213 #undef inet_ntoa
214 #endif
215 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
216
217 int ast_utils_init(void);
218 int ast_wait_for_input(int fd, int ms);
219
220 /*! Compares the source address and port of two sockaddr_in */
221 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
222 {
223         return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) 
224                 || (sin1->sin_port != sin2->sin_port));
225 }
226
227 #define AST_STACKSIZE 256 * 1024
228 #define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0)
229 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize);
230
231 /*!
232         \brief Process a string to find and replace characters
233         \param start The string to analyze
234         \param find The character to find
235         \param replace_with The character that will replace the one we are looking for
236 */
237 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
238
239 #ifndef HAVE_GETLOADAVG
240 int getloadavg(double *list, int nelem);
241 #endif
242
243 #ifdef linux
244 #define ast_random random
245 #else
246 long int ast_random(void);
247 #endif
248
249 /*!
250   \brief A wrapper for malloc()
251
252   ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
253   message in the case that the allocation fails.
254
255   The argument and return value are the same as malloc()
256 */
257 #define ast_malloc(len) \
258         _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
259
260 AST_INLINE_API(
261 void *_ast_malloc(size_t len, const char *file, int lineno, const char *func),
262 {
263         void *p;
264
265         p = malloc(len);
266
267         if (!p)
268                 ast_log(LOG_ERROR, "Memory Allocation Failure - '%d' bytes in function %s at line %d of %s\n", (int)len, func, lineno, file);
269
270         return p;
271 }
272 )
273
274 /*!
275   \brief A wrapper for calloc()
276
277   ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
278   message in the case that the allocation fails.
279
280   The arguments and return value are the same as calloc()
281 */
282 #define ast_calloc(num, len) \
283         _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
284
285 AST_INLINE_API(
286 void *_ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
287 {
288         void *p;
289
290         p = calloc(num, len);
291
292         if (!p)
293                 ast_log(LOG_ERROR, "Memory Allocation Failure - '%d' bytes in function %s at line %d of %s\n", (int)len, func, lineno, file);
294
295         return p;
296 }
297 )
298
299 /*!
300   \brief A wrapper for realloc()
301
302   ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
303   message in the case that the allocation fails.
304
305   The arguments and return value are the same as realloc()
306 */
307 #define ast_realloc(p, len) \
308         _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
309
310 AST_INLINE_API(
311 void *_ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
312 {
313         void *newp;
314
315         newp = realloc(p, len);
316
317         if (!newp)
318                 ast_log(LOG_ERROR, "Memory Allocation Failure - '%d' bytes in function %s at line %d of %s\n", (int)len, func, lineno, file);
319
320         return newp;
321 }
322 )
323
324 /*!
325   \brief A wrapper for strdup()
326
327   ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
328   message in the case that the allocation fails.
329
330   ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
331   argument is provided, ast_strdup will return NULL without generating any
332   kind of error log message.
333
334   The argument and return value are the same as strdup()
335 */
336 #define ast_strdup(str) \
337         _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
338
339 AST_INLINE_API(
340 char *_ast_strdup(const char *str, const char *file, int lineno, const char *func),
341 {
342         char *newstr = NULL;
343
344         if (str) {
345                 newstr = strdup(str);
346
347                 if (!newstr)
348                         ast_log(LOG_ERROR, "Memory Allocation Failure - Could not duplicate '%s' in function %s at line %d of %s\n", str, func, lineno, file);
349         }
350
351         return newstr;
352 }
353 )
354
355 /*!
356   \brief A wrapper for strndup()
357
358   ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
359   message in the case that the allocation fails.
360
361   ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
362   string to duplicate. If a NULL argument is provided, ast_strdup will return  
363   NULL without generating any kind of error log message.
364
365   The arguments and return value are the same as strndup()
366 */
367 #define ast_strndup(str, len) \
368         _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
369
370 AST_INLINE_API(
371 char *_ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
372 {
373         char *newstr = NULL;
374
375         if (str) {
376                 newstr = strndup(str, len);
377
378                 if (!newstr)
379                         ast_log(LOG_ERROR, "Memory Allocation Failure - Could not duplicate '%d' bytes of '%s' in function %s at line %d of %s\n", (int)len, str, func, lineno, file);
380         }
381
382         return newstr;
383 }
384 )
385
386 #if !defined(ast_strdupa) && defined(__GNUC__)
387 /*!
388   \brief duplicate a string in memory from the stack
389   \param s The string to duplicate
390
391   This macro will duplicate the given string.  It returns a pointer to the stack
392   allocatted memory for the new string.
393 */
394 #define ast_strdupa(s)                                                    \
395         (__extension__                                                    \
396         ({                                                                \
397                 const char *__old = (s);                                  \
398                 size_t __len = strlen(__old) + 1;                         \
399                 char *__new = __builtin_alloca(__len);                    \
400                 if (__builtin_expect(!__new, 0))                          \
401                         ast_log(LOG_ERROR, "Stack Allocation Error in"    \
402                                 "function '%s' at line '%d' of '%s'!\n",  \
403                                 __PRETTY_FUNCTION__, __LINE__, __FILE__); \
404                 else                                                      \
405                         memcpy (__new, __old, __len);                     \
406                 __new;                                                    \
407         }))
408 #endif
409
410 #endif /* _ASTERISK_UTILS_H */