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 (((sizeof(void *) * 8 * 8) - 16) * 1024)
00266
00267 #if defined(LOW_MEMORY)
00268 #define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
00269 #else
00270 #define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
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_ptr(void *ptr) attribute_unused;
00312 static void ast_free_ptr(void *ptr)
00313 {
00314 free(ptr);
00315 }
00316 #else
00317 #define ast_free free
00318 #define ast_free_ptr ast_free
00319 #endif
00320
00321 #ifndef __AST_DEBUG_MALLOC
00322
00323 #define MALLOC_FAILURE_MSG \
00324 ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
00325
00326
00327
00328
00329
00330
00331
00332
00333 #define ast_malloc(len) \
00334 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00335
00336 AST_INLINE_API(
00337 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
00338 {
00339 void *p;
00340
00341 if (!(p = malloc(len)))
00342 MALLOC_FAILURE_MSG;
00343
00344 return p;
00345 }
00346 )
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 #define ast_calloc(num, len) \
00357 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00358
00359 AST_INLINE_API(
00360 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
00361 {
00362 void *p;
00363
00364 if (!(p = calloc(num, len)))
00365 MALLOC_FAILURE_MSG;
00366
00367 return p;
00368 }
00369 )
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 #define ast_calloc_cache(num, len) \
00382 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 #define ast_realloc(p, len) \
00393 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00394
00395 AST_INLINE_API(
00396 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
00397 {
00398 void *newp;
00399
00400 if (!(newp = realloc(p, len)))
00401 MALLOC_FAILURE_MSG;
00402
00403 return newp;
00404 }
00405 )
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 #define ast_strdup(str) \
00420 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00421
00422 AST_INLINE_API(
00423 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
00424 {
00425 char *newstr = NULL;
00426
00427 if (str) {
00428 if (!(newstr = strdup(str)))
00429 MALLOC_FAILURE_MSG;
00430 }
00431
00432 return newstr;
00433 }
00434 )
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 #define ast_strndup(str, len) \
00449 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00450
00451 AST_INLINE_API(
00452 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
00453 {
00454 char *newstr = NULL;
00455
00456 if (str) {
00457 if (!(newstr = strndup(str, len)))
00458 MALLOC_FAILURE_MSG;
00459 }
00460
00461 return newstr;
00462 }
00463 )
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 #define ast_asprintf(ret, fmt, ...) \
00474 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
00475
00476 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...) __attribute__((format(printf, 5, 6)));
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 #define ast_vasprintf(ret, fmt, ap) \
00487 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
00488
00489 AST_INLINE_API(
00490 int __attribute__((format(printf, 5, 0))) _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
00491 {
00492 int res;
00493
00494 if ((res = vasprintf(ret, fmt, ap)) == -1)
00495 MALLOC_FAILURE_MSG;
00496
00497 return res;
00498 }
00499 )
00500
00501 #endif
00502
00503 #if !defined(ast_strdupa) && defined(__GNUC__)
00504
00505
00506
00507
00508
00509
00510
00511 #define ast_strdupa(s) \
00512 (__extension__ \
00513 ({ \
00514 const char *__old = (s); \
00515 size_t __len = strlen(__old) + 1; \
00516 char *__new = __builtin_alloca(__len); \
00517 memcpy (__new, __old, __len); \
00518 __new; \
00519 }))
00520 #endif
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535 void ast_enable_packet_fragmentation(int sock);
00536
00537 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
00538
00539 #ifdef AST_DEVMODE
00540 #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00541 static void force_inline _ast_assert(int condition, const char *condition_str,
00542 const char *file, int line, const char *function)
00543 {
00544 if (__builtin_expect(!condition, 1)) {
00545
00546
00547 ast_log(LOG_ERROR, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
00548 condition_str, condition, line, function, file);
00549 fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
00550 condition_str, condition, line, function, file);
00551
00552
00553 usleep(1);
00554 #ifdef DO_CRASH
00555 abort();
00556
00557
00558 *((int*)0)=0;
00559 #endif
00560 }
00561 }
00562 #else
00563 #define ast_assert(a)
00564 #endif
00565
00566
00567
00568
00569
00570
00571
00572
00573 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size);
00574
00575 #endif