d2db42e07dccb2e35d58eae8963329dad6e28075
[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 /*! ast_carefulwrite
221         \brief Try to write string, but wait no more than ms milliseconds
222         before timing out.
223
224         \note If you are calling ast_carefulwrite, it is assumed that you are calling
225         it on a file descriptor that _DOES_ have NONBLOCK set.  This way,
226         there is only one system call made to do a write, unless we actually
227         have a need to wait.  This way, we get better performance.
228 */
229 int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
230
231 /*! Compares the source address and port of two sockaddr_in */
232 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
233 {
234         return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) 
235                 || (sin1->sin_port != sin2->sin_port));
236 }
237
238 #define AST_STACKSIZE 256 * 1024
239
240 void ast_register_thread(char *name);
241 void ast_unregister_thread(void *id);
242
243 #define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0, \
244          __FILE__, __FUNCTION__, __LINE__, #c)
245 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize,
246         const char *file, const char *caller, int line, const char *start_fn);
247
248 /*!
249         \brief Process a string to find and replace characters
250         \param start The string to analyze
251         \param find The character to find
252         \param replace_with The character that will replace the one we are looking for
253 */
254 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
255
256 #ifndef HAVE_GETLOADAVG
257 int getloadavg(double *list, int nelem);
258 #endif
259
260 #ifdef linux
261 #define ast_random random
262 #else
263 long int ast_random(void);
264 #endif
265
266 #ifndef __AST_DEBUG_MALLOC
267
268 /*!
269   \brief A wrapper for malloc()
270
271   ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
272   message in the case that the allocation fails.
273
274   The argument and return value are the same as malloc()
275 */
276 #define ast_malloc(len) \
277         _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
278
279 AST_INLINE_API(
280 void * __attribute__((malloc)) _ast_malloc(size_t len, const char *file, int lineno, const char *func),
281 {
282         void *p;
283
284         p = malloc(len);
285
286         if (!p)
287                 ast_log(LOG_ERROR, "Memory Allocation Failure - '%d' bytes in function %s at line %d of %s\n", (int)len, func, lineno, file);
288
289         return p;
290 }
291 )
292
293 /*!
294   \brief A wrapper for calloc()
295
296   ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
297   message in the case that the allocation fails.
298
299   The arguments and return value are the same as calloc()
300 */
301 #define ast_calloc(num, len) \
302         _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
303
304 AST_INLINE_API(
305 void * __attribute__((malloc)) _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
306 {
307         void *p;
308
309         p = calloc(num, len);
310
311         if (!p)
312                 ast_log(LOG_ERROR, "Memory Allocation Failure - '%d' bytes in function %s at line %d of %s\n", (int)len, func, lineno, file);
313
314         return p;
315 }
316 )
317
318 /*!
319   \brief A wrapper for realloc()
320
321   ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
322   message in the case that the allocation fails.
323
324   The arguments and return value are the same as realloc()
325 */
326 #define ast_realloc(p, len) \
327         _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
328
329 AST_INLINE_API(
330 void * __attribute__((malloc)) _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
331 {
332         void *newp;
333
334         newp = realloc(p, len);
335
336         if (!newp)
337                 ast_log(LOG_ERROR, "Memory Allocation Failure - '%d' bytes in function %s at line %d of %s\n", (int)len, func, lineno, file);
338
339         return newp;
340 }
341 )
342
343 /*!
344   \brief A wrapper for strdup()
345
346   ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
347   message in the case that the allocation fails.
348
349   ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
350   argument is provided, ast_strdup will return NULL without generating any
351   kind of error log message.
352
353   The argument and return value are the same as strdup()
354 */
355 #define ast_strdup(str) \
356         _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
357
358 AST_INLINE_API(
359 char * __attribute__((malloc)) _ast_strdup(const char *str, const char *file, int lineno, const char *func),
360 {
361         char *newstr = NULL;
362
363         if (str) {
364                 newstr = strdup(str);
365
366                 if (!newstr)
367                         ast_log(LOG_ERROR, "Memory Allocation Failure - Could not duplicate '%s' in function %s at line %d of %s\n", str, func, lineno, file);
368         }
369
370         return newstr;
371 }
372 )
373
374 /*!
375   \brief A wrapper for strndup()
376
377   ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
378   message in the case that the allocation fails.
379
380   ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
381   string to duplicate. If a NULL argument is provided, ast_strdup will return  
382   NULL without generating any kind of error log message.
383
384   The arguments and return value are the same as strndup()
385 */
386 #define ast_strndup(str, len) \
387         _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
388
389 AST_INLINE_API(
390 char * __attribute__((malloc)) _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
391 {
392         char *newstr = NULL;
393
394         if (str) {
395                 newstr = strndup(str, len);
396
397                 if (!newstr)
398                         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);
399         }
400
401         return newstr;
402 }
403 )
404
405 #else
406
407 /* If astmm is in use, let it handle these.  Otherwise, it will report that
408    all allocations are coming from this header file */
409
410 #define ast_malloc(a)           malloc(a)
411 #define ast_calloc(a,b)         calloc(a,b)
412 #define ast_realloc(a,b)        realloc(a,b)
413 #define ast_strdup(a)           strdup(a)
414 #define ast_strndup(a,b)        strndup(a,b)
415
416 #endif /* AST_DEBUG_MALLOC */
417
418 #if !defined(ast_strdupa) && defined(__GNUC__)
419 /*!
420   \brief duplicate a string in memory from the stack
421   \param s The string to duplicate
422
423   This macro will duplicate the given string.  It returns a pointer to the stack
424   allocatted memory for the new string.
425 */
426 #define ast_strdupa(s)                                                    \
427         (__extension__                                                    \
428         ({                                                                \
429                 const char *__old = (s);                                  \
430                 size_t __len = strlen(__old) + 1;                         \
431                 char *__new = __builtin_alloca(__len);                    \
432                 if (__builtin_expect(!__new, 0))                          \
433                         ast_log(LOG_ERROR, "Stack Allocation Error in"    \
434                                 "function '%s' at line '%d' of '%s'!\n",  \
435                                 __PRETTY_FUNCTION__, __LINE__, __FILE__); \
436                 else                                                      \
437                         memcpy (__new, __old, __len);                     \
438                 __new;                                                    \
439         }))
440 #endif
441
442 #endif /* _ASTERISK_UTILS_H */