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