00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef _ASTERISK_UTILS_H
00024 #define _ASTERISK_UTILS_H
00025
00026 #include "asterisk/compat.h"
00027
00028 #include <stdlib.h>
00029 #include <stdio.h>
00030 #include <stdarg.h>
00031 #include <netinet/in.h>
00032 #include <arpa/inet.h>
00033 #include <netdb.h>
00034 #include <limits.h>
00035
00036 #include "asterisk/lock.h"
00037 #include "asterisk/time.h"
00038 #include "asterisk/strings.h"
00039 #include "asterisk/logger.h"
00040 #include "asterisk/compiler.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 extern unsigned int __unsigned_int_flags_dummy;
00066
00067 #define ast_test_flag(p,flag) ({ \
00068 typeof ((p)->flags) __p = (p)->flags; \
00069 typeof (__unsigned_int_flags_dummy) __x = 0; \
00070 (void) (&__p == &__x); \
00071 ((p)->flags & (flag)); \
00072 })
00073
00074 #define ast_set_flag(p,flag) do { \
00075 typeof ((p)->flags) __p = (p)->flags; \
00076 typeof (__unsigned_int_flags_dummy) __x = 0; \
00077 (void) (&__p == &__x); \
00078 ((p)->flags |= (flag)); \
00079 } while(0)
00080
00081 #define ast_clear_flag(p,flag) do { \
00082 typeof ((p)->flags) __p = (p)->flags; \
00083 typeof (__unsigned_int_flags_dummy) __x = 0; \
00084 (void) (&__p == &__x); \
00085 ((p)->flags &= ~(flag)); \
00086 } while(0)
00087
00088 #define ast_copy_flags(dest,src,flagz) do { \
00089 typeof ((dest)->flags) __d = (dest)->flags; \
00090 typeof ((src)->flags) __s = (src)->flags; \
00091 typeof (__unsigned_int_flags_dummy) __x = 0; \
00092 (void) (&__d == &__x); \
00093 (void) (&__s == &__x); \
00094 (dest)->flags &= ~(flagz); \
00095 (dest)->flags |= ((src)->flags & (flagz)); \
00096 } while (0)
00097
00098 #define ast_set2_flag(p,value,flag) do { \
00099 typeof ((p)->flags) __p = (p)->flags; \
00100 typeof (__unsigned_int_flags_dummy) __x = 0; \
00101 (void) (&__p == &__x); \
00102 if (value) \
00103 (p)->flags |= (flag); \
00104 else \
00105 (p)->flags &= ~(flag); \
00106 } while (0)
00107
00108 #define ast_set_flags_to(p,flag,value) do { \
00109 typeof ((p)->flags) __p = (p)->flags; \
00110 typeof (__unsigned_int_flags_dummy) __x = 0; \
00111 (void) (&__p == &__x); \
00112 (p)->flags &= ~(flag); \
00113 (p)->flags |= (value); \
00114 } while (0)
00115
00116
00117
00118
00119 #define ast_test_flag_nonstd(p,flag) \
00120 ((p)->flags & (flag))
00121
00122 #define ast_set_flag_nonstd(p,flag) do { \
00123 ((p)->flags |= (flag)); \
00124 } while(0)
00125
00126 #define ast_clear_flag_nonstd(p,flag) do { \
00127 ((p)->flags &= ~(flag)); \
00128 } while(0)
00129
00130 #define ast_copy_flags_nonstd(dest,src,flagz) do { \
00131 (dest)->flags &= ~(flagz); \
00132 (dest)->flags |= ((src)->flags & (flagz)); \
00133 } while (0)
00134
00135 #define ast_set2_flag_nonstd(p,value,flag) do { \
00136 if (value) \
00137 (p)->flags |= (flag); \
00138 else \
00139 (p)->flags &= ~(flag); \
00140 } while (0)
00141
00142 #define AST_FLAGS_ALL UINT_MAX
00143
00144 struct ast_flags {
00145 unsigned int flags;
00146 };
00147
00148 struct ast_hostent {
00149 struct hostent hp;
00150 char buf[1024];
00151 };
00152
00153 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
00154
00155
00156
00157 void ast_md5_hash(char *output, char *input);
00158
00159
00160 void ast_sha1_hash(char *output, char *input);
00161
00162 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);
00163 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
00164 int ast_base64decode(unsigned char *dst, const char *src, int max);
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved);
00182
00183
00184
00185
00186 void ast_uri_decode(char *s);
00187
00188 static force_inline void ast_slinear_saturated_add(short *input, short *value)
00189 {
00190 int res;
00191
00192 res = (int) *input + *value;
00193 if (res > 32767)
00194 *input = 32767;
00195 else if (res < -32767)
00196 *input = -32767;
00197 else
00198 *input = (short) res;
00199 }
00200
00201 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
00202 {
00203 int res;
00204
00205 res = (int) *input * *value;
00206 if (res > 32767)
00207 *input = 32767;
00208 else if (res < -32767)
00209 *input = -32767;
00210 else
00211 *input = (short) res;
00212 }
00213
00214 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
00215 {
00216 *input /= *value;
00217 }
00218
00219 int test_for_thread_safety(void);
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 const char *ast_inet_ntoa(struct in_addr ia);
00232
00233 #ifdef inet_ntoa
00234 #undef inet_ntoa
00235 #endif
00236 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
00237
00238 int ast_utils_init(void);
00239 int ast_wait_for_input(int fd, int ms);
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
00251
00252
00253 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
00254 {
00255 return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr)
00256 || (sin1->sin_port != sin2->sin_port));
00257 }
00258
00259 #define AST_STACKSIZE 240 * 1024
00260
00261 #if defined(LOW_MEMORY)
00262 #define AST_BACKGROUND_STACKSIZE 48 * 1024
00263 #else
00264 #define AST_BACKGROUND_STACKSIZE 240 * 1024
00265 #endif
00266
00267 void ast_register_thread(char *name);
00268 void ast_unregister_thread(void *id);
00269
00270 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
00271 void *data, size_t stacksize, const char *file, const char *caller,
00272 int line, const char *start_fn);
00273
00274 #define ast_pthread_create(a, b, c, d) ast_pthread_create_stack(a, b, c, d, \
00275 0, \
00276 __FILE__, __FUNCTION__, \
00277 __LINE__, #c)
00278
00279 #define ast_pthread_create_background(a, b, c, d) ast_pthread_create_stack(a, b, c, d, \
00280 AST_BACKGROUND_STACKSIZE, \
00281 __FILE__, __FUNCTION__, \
00282 __LINE__, #c)
00283
00284
00285
00286
00287
00288
00289
00290 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
00291
00292 #ifdef linux
00293 #define ast_random random
00294 #else
00295 long int ast_random(void);
00296 #endif
00297
00298
00299
00300
00301
00302
00303
00304 #ifdef __AST_DEBUG_MALLOC
00305 static void ast_free(void *ptr) attribute_unused;
00306 static void ast_free(void *ptr)
00307 {
00308 free(ptr);
00309 }
00310 #else
00311 #define ast_free free
00312 #endif
00313
00314 #ifndef __AST_DEBUG_MALLOC
00315
00316 #define MALLOC_FAILURE_MSG \
00317 ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
00318
00319
00320
00321
00322
00323
00324
00325
00326 #define ast_malloc(len) \
00327 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00328
00329 AST_INLINE_API(
00330 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
00331 {
00332 void *p;
00333
00334 if (!(p = malloc(len)))
00335 MALLOC_FAILURE_MSG;
00336
00337 return p;
00338 }
00339 )
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 #define ast_calloc(num, len) \
00350 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00351
00352 AST_INLINE_API(
00353 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
00354 {
00355 void *p;
00356
00357 if (!(p = calloc(num, len)))
00358 MALLOC_FAILURE_MSG;
00359
00360 return p;
00361 }
00362 )
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 #define ast_calloc_cache(num, len) \
00375 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 #define ast_realloc(p, len) \
00386 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00387
00388 AST_INLINE_API(
00389 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
00390 {
00391 void *newp;
00392
00393 if (!(newp = realloc(p, len)))
00394 MALLOC_FAILURE_MSG;
00395
00396 return newp;
00397 }
00398 )
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 #define ast_strdup(str) \
00413 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00414
00415 AST_INLINE_API(
00416 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
00417 {
00418 char *newstr = NULL;
00419
00420 if (str) {
00421 if (!(newstr = strdup(str)))
00422 MALLOC_FAILURE_MSG;
00423 }
00424
00425 return newstr;
00426 }
00427 )
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 #define ast_strndup(str, len) \
00442 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00443
00444 AST_INLINE_API(
00445 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
00446 {
00447 char *newstr = NULL;
00448
00449 if (str) {
00450 if (!(newstr = strndup(str, len)))
00451 MALLOC_FAILURE_MSG;
00452 }
00453
00454 return newstr;
00455 }
00456 )
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 #define ast_asprintf(ret, fmt, ...) \
00467 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
00468
00469 AST_INLINE_API(
00470 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...),
00471 {
00472 int res;
00473 va_list ap;
00474
00475 va_start(ap, fmt);
00476 if ((res = vasprintf(ret, fmt, ap)) == -1)
00477 MALLOC_FAILURE_MSG;
00478 va_end(ap);
00479
00480 return res;
00481 }
00482 )
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 #define ast_vasprintf(ret, fmt, ap) \
00493 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
00494
00495 AST_INLINE_API(
00496 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
00497 {
00498 int res;
00499
00500 if ((res = vasprintf(ret, fmt, ap)) == -1)
00501 MALLOC_FAILURE_MSG;
00502
00503 return res;
00504 }
00505 )
00506
00507 #else
00508
00509
00510
00511
00512 #define ast_malloc(a) malloc(a)
00513 #define ast_calloc(a,b) calloc(a,b)
00514 #define ast_realloc(a,b) realloc(a,b)
00515 #define ast_strdup(a) strdup(a)
00516 #define ast_strndup(a,b) strndup(a,b)
00517 #define ast_asprintf(a,b,c) asprintf(a,b,c)
00518 #define ast_vasprintf(a,b,c) vasprintf(a,b,c)
00519
00520 #endif
00521
00522 #if !defined(ast_strdupa) && defined(__GNUC__)
00523
00524
00525
00526
00527
00528
00529
00530 #define ast_strdupa(s) \
00531 (__extension__ \
00532 ({ \
00533 const char *__old = (s); \
00534 size_t __len = strlen(__old) + 1; \
00535 char *__new = __builtin_alloca(__len); \
00536 memcpy (__new, __old, __len); \
00537 __new; \
00538 }))
00539 #endif
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 void ast_enable_packet_fragmentation(int sock);
00555
00556 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
00557
00558 #endif