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/network.h"
00027
00028 #include <time.h>
00029 #include <unistd.h>
00030 #include <string.h>
00031
00032 #include "asterisk/lock.h"
00033 #include "asterisk/time.h"
00034 #include "asterisk/logger.h"
00035 #include "asterisk/localtime.h"
00036 #include "asterisk/stringfields.h"
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 extern unsigned int __unsigned_int_flags_dummy;
00062
00063 #define ast_test_flag(p,flag) ({ \
00064 typeof ((p)->flags) __p = (p)->flags; \
00065 typeof (__unsigned_int_flags_dummy) __x = 0; \
00066 (void) (&__p == &__x); \
00067 ((p)->flags & (flag)); \
00068 })
00069
00070 #define ast_set_flag(p,flag) do { \
00071 typeof ((p)->flags) __p = (p)->flags; \
00072 typeof (__unsigned_int_flags_dummy) __x = 0; \
00073 (void) (&__p == &__x); \
00074 ((p)->flags |= (flag)); \
00075 } while(0)
00076
00077 #define ast_clear_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_copy_flags(dest,src,flagz) do { \
00085 typeof ((dest)->flags) __d = (dest)->flags; \
00086 typeof ((src)->flags) __s = (src)->flags; \
00087 typeof (__unsigned_int_flags_dummy) __x = 0; \
00088 (void) (&__d == &__x); \
00089 (void) (&__s == &__x); \
00090 (dest)->flags &= ~(flagz); \
00091 (dest)->flags |= ((src)->flags & (flagz)); \
00092 } while (0)
00093
00094 #define ast_set2_flag(p,value,flag) do { \
00095 typeof ((p)->flags) __p = (p)->flags; \
00096 typeof (__unsigned_int_flags_dummy) __x = 0; \
00097 (void) (&__p == &__x); \
00098 if (value) \
00099 (p)->flags |= (flag); \
00100 else \
00101 (p)->flags &= ~(flag); \
00102 } while (0)
00103
00104 #define ast_set_flags_to(p,flag,value) do { \
00105 typeof ((p)->flags) __p = (p)->flags; \
00106 typeof (__unsigned_int_flags_dummy) __x = 0; \
00107 (void) (&__p == &__x); \
00108 (p)->flags &= ~(flag); \
00109 (p)->flags |= (value); \
00110 } while (0)
00111
00112
00113
00114
00115
00116
00117
00118 extern uint64_t __unsigned_int_flags_dummy64;
00119
00120 #define ast_test_flag64(p,flag) ({ \
00121 typeof ((p)->flags) __p = (p)->flags; \
00122 typeof (__unsigned_int_flags_dummy64) __x = 0; \
00123 (void) (&__p == &__x); \
00124 ((p)->flags & (flag)); \
00125 })
00126
00127 #define ast_set_flag64(p,flag) do { \
00128 typeof ((p)->flags) __p = (p)->flags; \
00129 typeof (__unsigned_int_flags_dummy64) __x = 0; \
00130 (void) (&__p == &__x); \
00131 ((p)->flags |= (flag)); \
00132 } while(0)
00133
00134 #define ast_clear_flag64(p,flag) do { \
00135 typeof ((p)->flags) __p = (p)->flags; \
00136 typeof (__unsigned_int_flags_dummy64) __x = 0; \
00137 (void) (&__p == &__x); \
00138 ((p)->flags &= ~(flag)); \
00139 } while(0)
00140
00141 #define ast_copy_flags64(dest,src,flagz) do { \
00142 typeof ((dest)->flags) __d = (dest)->flags; \
00143 typeof ((src)->flags) __s = (src)->flags; \
00144 typeof (__unsigned_int_flags_dummy64) __x = 0; \
00145 (void) (&__d == &__x); \
00146 (void) (&__s == &__x); \
00147 (dest)->flags &= ~(flagz); \
00148 (dest)->flags |= ((src)->flags & (flagz)); \
00149 } while (0)
00150
00151 #define ast_set2_flag64(p,value,flag) do { \
00152 typeof ((p)->flags) __p = (p)->flags; \
00153 typeof (__unsigned_int_flags_dummy64) __x = 0; \
00154 (void) (&__p == &__x); \
00155 if (value) \
00156 (p)->flags |= (flag); \
00157 else \
00158 (p)->flags &= ~(flag); \
00159 } while (0)
00160
00161 #define ast_set_flags_to64(p,flag,value) do { \
00162 typeof ((p)->flags) __p = (p)->flags; \
00163 typeof (__unsigned_int_flags_dummy64) __x = 0; \
00164 (void) (&__p == &__x); \
00165 (p)->flags &= ~(flag); \
00166 (p)->flags |= (value); \
00167 } while (0)
00168
00169
00170
00171
00172
00173 #define ast_test_flag_nonstd(p,flag) \
00174 ((p)->flags & (flag))
00175
00176 #define ast_set_flag_nonstd(p,flag) do { \
00177 ((p)->flags |= (flag)); \
00178 } while(0)
00179
00180 #define ast_clear_flag_nonstd(p,flag) do { \
00181 ((p)->flags &= ~(flag)); \
00182 } while(0)
00183
00184 #define ast_copy_flags_nonstd(dest,src,flagz) do { \
00185 (dest)->flags &= ~(flagz); \
00186 (dest)->flags |= ((src)->flags & (flagz)); \
00187 } while (0)
00188
00189 #define ast_set2_flag_nonstd(p,value,flag) do { \
00190 if (value) \
00191 (p)->flags |= (flag); \
00192 else \
00193 (p)->flags &= ~(flag); \
00194 } while (0)
00195
00196 #define AST_FLAGS_ALL UINT_MAX
00197
00198
00199
00200 struct ast_flags {
00201 unsigned int flags;
00202 };
00203
00204
00205
00206 struct ast_flags64 {
00207 uint64_t flags;
00208 };
00209
00210 struct ast_hostent {
00211 struct hostent hp;
00212 char buf[1024];
00213 };
00214
00215
00216 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
00217
00218
00219 void ast_md5_hash(char *output, const char *input);
00220
00221 void ast_sha1_hash(char *output, const char *input);
00222
00223 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);
00224
00225 #undef MIN
00226 #define MIN(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a > __b) ? __b : __a);})
00227 #undef MAX
00228 #define MAX(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a < __b) ? __b : __a);})
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 int ast_base64decode(unsigned char *dst, const char *src, int max);
00250
00251 #define AST_URI_ALPHANUM (1 << 0)
00252 #define AST_URI_MARK (1 << 1)
00253 #define AST_URI_UNRESERVED (AST_URI_ALPHANUM | AST_URI_MARK)
00254 #define AST_URI_LEGACY_SPACE (1 << 2)
00255
00256 #define AST_URI_SIP_USER_UNRESERVED (1 << 20)
00257
00258 extern const struct ast_flags ast_uri_http;
00259 extern const struct ast_flags ast_uri_http_legacy;
00260 extern const struct ast_flags ast_uri_sip_user;
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 char *ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec);
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 void ast_uri_decode(char *s, struct ast_flags spec);
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 char *ast_escape_quoted(const char *string, char *outbuf, int buflen);
00303
00304 static force_inline void ast_slinear_saturated_add(short *input, short *value)
00305 {
00306 int res;
00307
00308 res = (int) *input + *value;
00309 if (res > 32767)
00310 *input = 32767;
00311 else if (res < -32767)
00312 *input = -32767;
00313 else
00314 *input = (short) res;
00315 }
00316
00317 static force_inline void ast_slinear_saturated_subtract(short *input, short *value)
00318 {
00319 int res;
00320
00321 res = (int) *input - *value;
00322 if (res > 32767)
00323 *input = 32767;
00324 else if (res < -32767)
00325 *input = -32767;
00326 else
00327 *input = (short) res;
00328 }
00329
00330 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
00331 {
00332 int res;
00333
00334 res = (int) *input * *value;
00335 if (res > 32767)
00336 *input = 32767;
00337 else if (res < -32767)
00338 *input = -32767;
00339 else
00340 *input = (short) res;
00341 }
00342
00343 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
00344 {
00345 *input /= *value;
00346 }
00347
00348 #ifdef localtime_r
00349 #undef localtime_r
00350 #endif
00351 #define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
00352
00353 int ast_utils_init(void);
00354 int ast_wait_for_input(int fd, int ms);
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 int ast_careful_fwrite(FILE *f, int fd, const char *s, size_t len, int timeoutms);
00385
00386
00387
00388
00389
00390 #define AST_STACKSIZE (((sizeof(void *) * 8 * 8) - 16) * 1024)
00391
00392 #if defined(LOW_MEMORY)
00393 #define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
00394 #else
00395 #define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
00396 #endif
00397
00398 void ast_register_thread(char *name);
00399 void ast_unregister_thread(void *id);
00400
00401 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
00402 void *data, size_t stacksize, const char *file, const char *caller,
00403 int line, const char *start_fn);
00404
00405 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void*(*start_routine)(void *),
00406 void *data, size_t stacksize, const char *file, const char *caller,
00407 int line, const char *start_fn);
00408
00409 #define ast_pthread_create(a, b, c, d) \
00410 ast_pthread_create_stack(a, b, c, d, \
00411 0, __FILE__, __FUNCTION__, __LINE__, #c)
00412
00413 #define ast_pthread_create_detached(a, b, c, d) \
00414 ast_pthread_create_detached_stack(a, b, c, d, \
00415 0, __FILE__, __FUNCTION__, __LINE__, #c)
00416
00417 #define ast_pthread_create_background(a, b, c, d) \
00418 ast_pthread_create_stack(a, b, c, d, \
00419 AST_BACKGROUND_STACKSIZE, \
00420 __FILE__, __FUNCTION__, __LINE__, #c)
00421
00422 #define ast_pthread_create_detached_background(a, b, c, d) \
00423 ast_pthread_create_detached_stack(a, b, c, d, \
00424 AST_BACKGROUND_STACKSIZE, \
00425 __FILE__, __FUNCTION__, __LINE__, #c)
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
00436
00437 long int ast_random(void);
00438
00439
00440
00441
00442
00443
00444
00445
00446 #ifdef __AST_DEBUG_MALLOC
00447 static void ast_free_ptr(void *ptr) attribute_unused;
00448 static void ast_free_ptr(void *ptr)
00449 {
00450 ast_free(ptr);
00451 }
00452 #else
00453 #define ast_free free
00454 #define ast_free_ptr ast_free
00455 #endif
00456
00457 #ifndef __AST_DEBUG_MALLOC
00458
00459 #define MALLOC_FAILURE_MSG \
00460 ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
00461
00462
00463
00464
00465
00466
00467
00468
00469 #define ast_malloc(len) \
00470 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00471
00472 AST_INLINE_API(
00473 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
00474 {
00475 void *p;
00476
00477 if (!(p = malloc(len)))
00478 MALLOC_FAILURE_MSG;
00479
00480 return p;
00481 }
00482 )
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 #define ast_calloc(num, len) \
00493 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00494
00495 AST_INLINE_API(
00496 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
00497 {
00498 void *p;
00499
00500 if (!(p = calloc(num, len)))
00501 MALLOC_FAILURE_MSG;
00502
00503 return p;
00504 }
00505 )
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 #define ast_calloc_cache(num, len) \
00518 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 #define ast_realloc(p, len) \
00529 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00530
00531 AST_INLINE_API(
00532 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
00533 {
00534 void *newp;
00535
00536 if (!(newp = realloc(p, len)))
00537 MALLOC_FAILURE_MSG;
00538
00539 return newp;
00540 }
00541 )
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 #define ast_strdup(str) \
00556 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00557
00558 AST_INLINE_API(
00559 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
00560 {
00561 char *newstr = NULL;
00562
00563 if (str) {
00564 if (!(newstr = strdup(str)))
00565 MALLOC_FAILURE_MSG;
00566 }
00567
00568 return newstr;
00569 }
00570 )
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 #define ast_strndup(str, len) \
00585 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
00586
00587 AST_INLINE_API(
00588 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
00589 {
00590 char *newstr = NULL;
00591
00592 if (str) {
00593 if (!(newstr = strndup(str, len)))
00594 MALLOC_FAILURE_MSG;
00595 }
00596
00597 return newstr;
00598 }
00599 )
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 #define ast_asprintf(ret, fmt, ...) \
00610 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
00611
00612 int __attribute__((format(printf, 5, 6)))
00613 _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...);
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 #define ast_vasprintf(ret, fmt, ap) \
00624 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
00625
00626 AST_INLINE_API(
00627 __attribute__((format(printf, 5, 0)))
00628 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
00629 {
00630 int res;
00631
00632 if ((res = vasprintf(ret, fmt, ap)) == -1)
00633 MALLOC_FAILURE_MSG;
00634
00635 return res;
00636 }
00637 )
00638
00639 #endif
00640
00641 #if !defined(ast_strdupa) && defined(__GNUC__)
00642
00643
00644
00645
00646
00647
00648
00649 #define ast_strdupa(s) \
00650 (__extension__ \
00651 ({ \
00652 const char *__old = (s); \
00653 size_t __len = strlen(__old) + 1; \
00654 char *__new = __builtin_alloca(__len); \
00655 memcpy (__new, __old, __len); \
00656 __new; \
00657 }))
00658 #endif
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673 void ast_enable_packet_fragmentation(int sock);
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 int ast_mkdir(const char *path, int mode);
00684
00685 #define ARRAY_LEN(a) (size_t) (sizeof(a) / sizeof(0[a]))
00686
00687
00688
00689 struct ast_http_digest {
00690 AST_DECLARE_STRING_FIELDS(
00691 AST_STRING_FIELD(username);
00692 AST_STRING_FIELD(nonce);
00693 AST_STRING_FIELD(uri);
00694 AST_STRING_FIELD(realm);
00695 AST_STRING_FIELD(domain);
00696 AST_STRING_FIELD(response);
00697 AST_STRING_FIELD(cnonce);
00698 AST_STRING_FIELD(opaque);
00699 AST_STRING_FIELD(nc);
00700 );
00701 int qop;
00702 };
00703
00704
00705
00706
00707
00708
00709
00710
00711 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic);
00712
00713
00714 #ifdef AST_DEVMODE
00715 #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00716 static void force_inline _ast_assert(int condition, const char *condition_str,
00717 const char *file, int line, const char *function)
00718 {
00719 if (__builtin_expect(!condition, 1)) {
00720
00721
00722 ast_log(__LOG_ERROR, file, line, function, "FRACK!, Failed assertion %s (%d)\n",
00723 condition_str, condition);
00724 fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
00725 condition_str, condition, line, function, file);
00726
00727
00728 usleep(1);
00729 #ifdef DO_CRASH
00730 abort();
00731
00732
00733 *((int*)0)=0;
00734 #endif
00735 }
00736 }
00737 #else
00738 #define ast_assert(a)
00739 #endif
00740
00741 #include "asterisk/strings.h"
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 #define ast_alignof(type) __alignof__(type)
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 #define ast_align_for(offset, type) (((offset + __alignof__(type) - 1) / __alignof__(type)) * __alignof__(type))
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794 #define ast_make_room_for(offset, type) (((offset + (2 * __alignof__(type) - 1)) / __alignof__(type)) * __alignof__(type))
00795
00796
00797
00798
00799 struct ast_eid {
00800 unsigned char eid[6];
00801 } __attribute__((__packed__));
00802
00803
00804
00805
00806
00807
00808
00809 extern struct ast_eid ast_eid_default;
00810
00811
00812
00813
00814
00815 void ast_set_default_eid(struct ast_eid *eid);
00816
00817
00818
00819
00820
00821 char *ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid);
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 int ast_str_to_eid(struct ast_eid *eid, const char *s);
00833
00834
00835
00836
00837
00838
00839
00840 int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
00841
00842
00843
00844
00845
00846
00847 int ast_get_tid(void);
00848
00849
00850
00851
00852
00853
00854
00855
00856 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size);
00857
00858 #endif