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
00037 #include "asterisk/lock.h"
00038 #include "asterisk/time.h"
00039 #include "asterisk/strings.h"
00040 #include "asterisk/logger.h"
00041 #include "asterisk/compiler.h"
00042 #include "asterisk/localtime.h"
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 extern unsigned int __unsigned_int_flags_dummy;
00068
00069 #define ast_test_flag(p,flag) ({ \
00070 typeof ((p)->flags) __p = (p)->flags; \
00071 typeof (__unsigned_int_flags_dummy) __x = 0; \
00072 (void) (&__p == &__x); \
00073 ((p)->flags & (flag)); \
00074 })
00075
00076 #define ast_set_flag(p,flag) do { \
00077 typeof ((p)->flags) __p = (p)->flags; \
00078 typeof (__unsigned_int_flags_dummy) __x = 0; \
00079 (void) (&__p == &__x); \
00080 ((p)->flags |= (flag)); \
00081 } while(0)
00082
00083 #define ast_clear_flag(p,flag) do { \
00084 typeof ((p)->flags) __p = (p)->flags; \
00085 typeof (__unsigned_int_flags_dummy) __x = 0; \
00086 (void) (&__p == &__x); \
00087 ((p)->flags &= ~(flag)); \
00088 } while(0)
00089
00090 #define ast_copy_flags(dest,src,flagz) do { \
00091 typeof ((dest)->flags) __d = (dest)->flags; \
00092 typeof ((src)->flags) __s = (src)->flags; \
00093 typeof (__unsigned_int_flags_dummy) __x = 0; \
00094 (void) (&__d == &__x); \
00095 (void) (&__s == &__x); \
00096 (dest)->flags &= ~(flagz); \
00097 (dest)->flags |= ((src)->flags & (flagz)); \
00098 } while (0)
00099
00100 #define ast_set2_flag(p,value,flag) do { \
00101 typeof ((p)->flags) __p = (p)->flags; \
00102 typeof (__unsigned_int_flags_dummy) __x = 0; \
00103 (void) (&__p == &__x); \
00104 if (value) \
00105 (p)->flags |= (flag); \
00106 else \
00107 (p)->flags &= ~(flag); \
00108 } while (0)
00109
00110 #define ast_set_flags_to(p,flag,value) do { \
00111 typeof ((p)->flags) __p = (p)->flags; \
00112 typeof (__unsigned_int_flags_dummy) __x = 0; \
00113 (void) (&__p == &__x); \
00114 (p)->flags &= ~(flag); \
00115 (p)->flags |= (value); \
00116 } while (0)
00117
00118
00119
00120
00121 #define ast_test_flag_nonstd(p,flag) \
00122 ((p)->flags & (flag))
00123
00124 #define ast_set_flag_nonstd(p,flag) do { \
00125 ((p)->flags |= (flag)); \
00126 } while(0)
00127
00128 #define ast_clear_flag_nonstd(p,flag) do { \
00129 ((p)->flags &= ~(flag)); \
00130 } while(0)
00131
00132 #define ast_copy_flags_nonstd(dest,src,flagz) do { \
00133 (dest)->flags &= ~(flagz); \
00134 (dest)->flags |= ((src)->flags & (flagz)); \
00135 } while (0)
00136
00137 #define ast_set2_flag_nonstd(p,value,flag) do { \
00138 if (value) \
00139 (p)->flags |= (flag); \
00140 else \
00141 (p)->flags &= ~(flag); \
00142 } while (0)
00143
00144 #define AST_FLAGS_ALL UINT_MAX
00145
00146 struct ast_flags {
00147 unsigned int flags;
00148 };
00149
00150 struct ast_hostent {
00151 struct hostent hp;
00152 char buf[1024];
00153 };
00154
00155 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
00156
00157
00158
00159 void ast_md5_hash(char *output, char *input);
00160
00161
00162 void ast_sha1_hash(char *output, char *input);
00163
00164 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);
00165 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
00166 int ast_base64decode(unsigned char *dst, const char *src, int max);
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved);
00184
00185
00186
00187
00188 void ast_uri_decode(char *s);
00189
00190 static force_inline void ast_slinear_saturated_add(short *input, short *value)
00191 {
00192 int res;
00193
00194 res = (int) *input + *value;
00195 if (res > 32767)
00196 *input = 32767;
00197 else if (res < -32767)
00198 *input = -32767;
00199 else
00200 *input = (short) res;
00201 }
00202
00203 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
00204 {
00205 int res;
00206
00207 res = (int) *input * *value;
00208 if (res > 32767)
00209 *input = 32767;
00210 else if (res < -32767)
00211 *input = -32767;
00212 else
00213 *input = (short) res;
00214 }
00215
00216 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
00217 {
00218 *input /= *value;
00219 }
00220
00221 int test_for_thread_safety(void);
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 const char *ast_inet_ntoa(struct in_addr ia);
00234
00235 #ifdef inet_ntoa
00236 #undef inet_ntoa
00237 #endif
00238 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
00239
00240 #ifdef localtime_r
00241 #undef localtime_r
00242 #endif
00243 #define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
00244
00245 int ast_utils_init(void);
00246 int ast_wait_for_input(int fd, int ms);
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
00258
00259
00260 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
00261 {
00262 return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr)
00263 || (sin1->sin_port != sin2->sin_port));
00264 }
00265
00266 #define AST_STACKSIZE 240 * 1024
00267
00268 #if defined(LOW_MEMORY)
00269 #define AST_BACKGROUND_STACKSIZE 48 * 1024
00270 #else
00271 #define AST_BACKGROUND_STACKSIZE 240 * 1024
00272 #endif
00273
00274 void ast_register_thread(char *name);
00275 void ast_unregister_thread(void *id);
00276
00277 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
00278 void *data, size_t stacksize, const char *file, const char *caller,
00279 int line, const char *start_fn);
00280
00281 #define ast_pthread_create(a, b, c, d) ast_pthread_create_stack(a, b, c, d, \
00282 0, \
00283 __FILE__, __FUNCTION__, \
00284 __LINE__, #c)
00285
00286 #define ast_pthread_create_background(a, b, c, d) ast_pthread_create_stack(a, b, c, d, \
00287 AST_BACKGROUND_STACKSIZE, \
00288 __FILE__, __FUNCTION__, \
00289 __LINE__, #c)
00290
00291
00292
00293
00294
00295
00296
00297 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
00298
00299 #ifdef linux
00300 #define ast_random random
00301 #else
00302 long int ast_random(void);
00303 #endif
00304
00305
00306
00307
00308
00309
00310
00311 #ifdef __AST_DEBUG_MALLOC
00312 static void ast_free(void *ptr) attribute_unused;
00313 static void ast_free(void *ptr)
00314 {
00315 free(ptr);
00316 }
00317 #else
00318 #define ast_free 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 AST_INLINE_API(
00477 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...),
00478 {
00479 int res;
00480 va_list ap;
00481
00482 va_start(ap, fmt);
00483 if ((res = vasprintf(ret, fmt, ap)) == -1)
00484 MALLOC_FAILURE_MSG;
00485 va_end(ap);
00486
00487 return res;
00488 }
00489 )
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 #define ast_vasprintf(ret, fmt, ap) \
00500 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
00501
00502 AST_INLINE_API(
00503 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
00504 {
00505 int res;
00506
00507 if ((res = vasprintf(ret, fmt, ap)) == -1)
00508 MALLOC_FAILURE_MSG;
00509
00510 return res;
00511 }
00512 )
00513
00514 #else
00515
00516
00517
00518
00519 #define ast_malloc(a) malloc(a)
00520 #define ast_calloc(a,b) calloc(a,b)
00521 #define ast_realloc(a,b) realloc(a,b)
00522 #define ast_strdup(a) strdup(a)
00523 #define ast_strndup(a,b) strndup(a,b)
00524 #define ast_asprintf(a,b,c) asprintf(a,b,c)
00525 #define ast_vasprintf(a,b,c) vasprintf(a,b,c)
00526
00527 #endif
00528
00529 #if !defined(ast_strdupa) && defined(__GNUC__)
00530
00531
00532
00533
00534
00535
00536
00537 #define ast_strdupa(s) \
00538 (__extension__ \
00539 ({ \
00540 const char *__old = (s); \
00541 size_t __len = strlen(__old) + 1; \
00542 char *__new = __builtin_alloca(__len); \
00543 memcpy (__new, __old, __len); \
00544 __new; \
00545 }))
00546 #endif
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 void ast_enable_packet_fragmentation(int sock);
00562
00563 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
00564
00565 #endif