1 /* errmac.h - Utility, debugging, and error checking macros 2 * 3 * Copyright (c) 1998,2001,2006,2010-2014 Sampo Kellomaki <sampo@iki.fi>, All Rights Reserved. 4 * Copyright (c) 2001-2008 Symlabs (symlabs@symlabs.com), All Rights Reserved. 5 * This is free software and comes with NO WARRANTY. Licensed under Apache2 license. 6 * $Id$ 7 * 8 * 10.1.2003, added option to make ASSERT nonfatal --Sampo 9 * 4.6.2003, added STRERROR() macro --Sampo 10 * 11.7.2003, added MUTEX_DEBUG, ASSERT_THR(), ASSERT_NOT_IN_LOCK() --Sampo 11 * 6.10.2003, added ALIGN128 (16 byte alignment) --Sampo 12 * 12.12.2003, added AK support to asserts --Sampo 13 * 15.1.2004, added STRNULLCHK() --Sampo 14 * 24.2.2006, made some definitions conditional --Sampo 15 * 15.4.2006, new adaptation over Easter holiday --Sampo 16 * 3.10.2007, added FLOCK() and FUNLOCK() --Sampo 17 * 22.3.2008, renamed debug to zx_debug to avoid conflicts in any .so module usage --Sampo 18 * 4.12.2010, fixed bug in locking where range was zero length --Sampo 19 * 4.12.2011, fixed bug in TOUPPER() macro --Sampo 20 * 30.10.2012, added AKBOX_FN() to logging --Sampo 21 */ 22 23 #ifndef _errmac_h 24 #define _errmac_h 25 26 #ifndef MAYBE_UNUSED 27 #define MAYBE_UNUSED __attribute__ ((unused)) 28 #endif 29 30 #ifdef MINGW 31 #include <windows.h> 32 #else 33 #include <pthread.h> 34 #endif 35 #include <stdio.h> /* For stderr */ 36 #include <stdint.h> 37 38 #ifdef USE_AKBOX_FN 39 #include "akbox.h" 40 #endif 41 42 /* CONFIG */ 43 44 #if 0 45 #define trace 1 46 #define assert_nonfatal 0 47 #else 48 extern int assert_nonfatal; 49 extern int trace; /* this gets manipulated by -v or similar flag */ 50 #endif 51 52 #define TCP_PROTO 6 /* never seen getprotobyname("tcp") return anything else */ 53 54 /* END CONFIG */ 55 56 /* For bracketing macros so that they appear as single statement. */ 57 /* Note: MB = MACRO_BEGIN, ME = MACRO_END */ 58 59 #define MB do { 60 #define ME } while(0) 61 62 #define unless(x) if(!(x)) 63 64 #define STRERROR(en) (strerror(en)?strerror(en):"???") 65 66 /* Since Solaris printf does not grog NULL pointers eve if field with is zero, we need to 67 * liberally apply an explicit NULL check whenever we call printf family (glibc printf 68 * is much more reasonable and does not require such silly checks). */ 69 #define STRNULLCHK(s) ((s)?(char*)(s):"") 70 #define STRNULLCHKQ(s) ((s)?(char*)(s):"?") 71 #define STRNULLCHKD(s) ((s)?(char*)(s):"-") 72 #define STRNULLCHKZ(s) ((s)?(char*)(s):"0") 73 #define STRNULLCHKNULL(s) ((s)?(char*)(s):"(null)") 74 75 /* Common datatypes */ 76 77 #ifndef U8 78 #define U8 unsigned char 79 #endif 80 #ifndef CU8 81 #define CU8 const unsigned char 82 #endif 83 84 #ifndef U16_MAX 85 #define U16_MAX 65535 86 #endif 87 #ifndef I16_MAX 88 #define I16_MAX 32767 89 #endif 90 #ifndef I32_MAX 91 #define I32_MAX 0x7fffffff 92 #endif 93 94 /* Pessimistic maximum string conversion lengths. 95 * 2^n == 10^x 96 * x = n * l(2)/l(10) ; l == ln or log 97 * 9 --> 3 chars + sign + NUL 98 * 13 = 3.9 --> 4 chars + sign + NUL 99 * 32 = 9.6 --> 10 chars + sign + NUL 100 * 64 = 19.2 --> 20 chars + sign + NUL = 22 101 * 102 * A double is 64 bits total, thus mantissa can never exceed 64 bit int. 103 * The exponent takes `E', sign, and length of the exponent of 16 bits. 104 */ 105 106 #define INTSTRLEN 22 107 #define DBLSTRLEN 30 108 109 /* WARNING: Many of these macros evaluate arguments more than once (and 110 * not all arguments get necessarily evaluated at all). Beware of 111 * passing return values of functions as arguments, because then the 112 * function may get called twice. */ 113 114 #define ABS(x) ( ((x) < 0) ? -(x) : (x) ) 115 #define IN_RANGE(x,a,b) ( ((x) >= (a)) ? ((x) <= (b)) : 0 ) 116 #define IN_RANGE_EXCLUSIVE(x,a,b) ( ((x) > (a)) ? ((x) < (b)) : 0 ) 117 118 /*#define WHITESPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')*/ 119 #define WHITESPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) =='\r' || (c) == '\f') 120 121 #ifndef MIN 122 #define MIN(a,b) ( ((a) < (b)) ? (a) : (b) ) 123 #endif 124 #ifndef MAX 125 #define MAX(a,b) ( ((a) > (b)) ? (a) : (b) ) 126 #endif 127 128 #define MIN3(a,b,c) MIN((a), MIN((b),(c))) 129 #define MIN4(a,b,c,d) MIN(MIN((a),(b)), MIN((c),(d))) 130 131 #define MAX3(a,b,c) MAX((a), MAX((b),(c))) 132 #define MAX4(a,b,c,d) MAX(MAX((a),(b)), MAX((c),(d))) 133 134 #define MINMAX(x,min,max) (MIN(MAX((x),(min)),(max))) 135 #define CLAMP(x,min,max) ((x) = MINMAX((x),(min),(max))) 136 137 #define ONE_OF_2(x,a,b) (((x) == (a)) || ((x) == (b))) 138 #define ONE_OF_3(x,a,b,c) (ONE_OF_2((x),(a),(b)) || ((x) == (c))) 139 #define ONE_OF_4(x,a,b,c,d) (ONE_OF_2((x),(a),(b)) || ONE_OF_2((x),(c),(d))) 140 #define ONE_OF_5(x,a,b,c,d,e) (ONE_OF_3((x),(a),(b),(c)) || ONE_OF_2((x),(d),(e))) 141 #define ONE_OF_6(x,a,b,c,d,e,f) (ONE_OF_3((x),(a),(b),(c)) || ONE_OF_3((x),(d),(e),(f))) 142 #define ONE_OF_7(x,a,b,c,d,e,f,g) (ONE_OF_4((x),(a),(b),(c),(g)) || ONE_OF_3((x),(d),(e),(f))) 143 #define ONE_OF_8(x,a,b,c,d,e,f,g,h) (ONE_OF_4((x),(a),(b),(c),(g)) || ONE_OF_4((x),(d),(e),(f),(h))) 144 145 #define THREE_IN_ROW(p,a,b,c) ((p)[0] == (a) && (p)[1] == (b) && (p)[2] == (c)) 146 147 #define STR_TERM '\0' 148 149 #define TOUPPER(x) (IN_RANGE(x, 'a', 'z') ? ((x) - ('a' - 'A')) : (x)) 150 #define TOLOWER(x) (IN_RANGE(x, 'A', 'Z') ? ((x) - ('A' - 'a')) : (x)) 151 152 #define BOOL_STR_TEST(x) ((x) && (x) != '0') 153 154 /* Copy memory and null terminate string. strncpy strings and 155 guarantee null termination (strncpy does not). */ 156 157 #define MEMCPYZ(to,fro,l) MB memcpy((to),(fro),(l)); (to)[(l)] = 0x00; ME 158 #define strnzcpy(to,f,l) MB strncpy((to),(f),(l)); (to)[(l)-1] = '\0'; ME 159 160 161 #define AZaz_09_(x) ( IN_RANGE((x), '0', '9') || ((x) == '_') || \ 162 IN_RANGE((x), 'A', 'Z') || IN_RANGE((x), 'a', 'z') ) 163 #define AZaz_09_dash(x) ( IN_RANGE((x), '0', '9') || ((x) == '_') || \ 164 ((x) == '-') || \ 165 IN_RANGE((x), 'A', 'Z') || IN_RANGE((x), 'a', 'z') ) 166 #define AZaz_09_dot(x) ( IN_RANGE((x), '0', '9') || ((x) == '_') || \ 167 ((x)=='.') || ((x) == '-') || \ 168 IN_RANGE((x), 'A', 'Z') || IN_RANGE((x), 'a', 'z') ) 169 #define AZaz_09_dot_plus(x) ( IN_RANGE((x), '0', '9') || ((x) == '_') || \ 170 ((x)=='.') || ((x) == '-') || ((x) == '+') || \ 171 IN_RANGE((x), 'A', 'Z') || IN_RANGE((x), 'a', 'z') ) 172 #define AZaz_(x) ( ((x) == '_') || \ 173 IN_RANGE((x), 'A', 'Z') || IN_RANGE((x), 'a', 'z') ) 174 #define IS_ALPHA(x) (IN_RANGE((x), 'A', 'Z') || IN_RANGE((x), 'a', 'z')) 175 #define IS_ALNUM(x) (IS_ALPHA(x) || IS_DIGIT(x) || (x) == '_') 176 177 /* Find the next newline starting from p and bound by e, set a to addr or 0 if not found */ 178 #define FIND_NL(a,p,e) MB for((a)=(p);((a)<(e))&&(*(a)!=0x0a);++(a));if((a)==(e)) (a)=0; ME 179 180 #define IS_DIGIT(x) IN_RANGE((x), '0', '9') 181 #define IS_HEX(x) ( IN_RANGE((x), '0', '9') || \ 182 IN_RANGE((x), 'A', 'F') || IN_RANGE((x), 'a', 'f') ) 183 184 #define HEX(x) (IN_RANGE((x), '0', '9') ? ((x) - '0') : (((x) & 0x07) + 9)) 185 #define HEX_DIGIT(x) (((x)<10) ? ((x) + '0') : ((x) - 10 + 'A')) 186 187 #define CONV_DIGIT(x) ((x) - '0') 188 189 #define LEAP(a) (!((a)%4) && (((a)%100) || !((a)%400))) /* Input full year, like 1984 or 2011 */ 190 191 #define ROUND_UP(x,n) if ((n) && (x) % (n)) x += (n) - (x) % (n); 192 193 /* Original Base64 Len (x+2) / 3 194 * "" "" 0 2 0(2) Suitable original(packed) sizes = bits 195 * 1 WX== 4 3 1(0) to avoid padding are 196 * 12 WXY= 4 4 1(1) 3(4) = 24, 6(8)= 48, 9(12)= 72, 12(16)= 96, 197 * 123 WXYZ 4 5 1(2) 15(20)=120, 18(24)=144, 21(28)=168, 24(32)=192, 198 * 1234 WXYZwx== 8 6 2(0) 27(36)=216, 30(40)=240, 33(44)=264, 36(48)=288 199 * 12345 WXYZwxy= 8 7 2(1) 200 * 123456 WXYZwxyz 8 8 2(2) 201 */ 202 #define SIMPLE_BASE64_LEN(x) (((x)+2) / 3 * 4) /* exact encoded length given binary length */ 203 #define SIMPLE_BASE64_PESSIMISTIC_DECODE_LEN(x) (((x)+3)/4*3) 204 #define DEFLATE_PESSIMISTIC_LEN(x) ((x)+((x)>>8)+12) /* zlib worst case: orig_size * 1.001 + 12, see also compressBound() */ 205 #define OAEP_LEN 41 /* Overhead of PKCS#1 v2.0 OAEP padding */ 206 207 /* Perform URL conversion in place 208 * src = dst = buffer_where_data_is; 209 * URL_DECODE(src,dst,buf+sizeof(buf)); 210 * *dst = 0; // nul terminate 211 * len = dst - buf; 212 * The dst pointer need not point to same buffer as src, though it can (to effectuate an 213 * in-place conversion). The converted length is the difference with original dst and final dst. 214 * src and dst MUST be different variables (even if they point to same place). 215 * lim is one beyond end of the src data. Resulting conversion is always shorter 216 * or equal to original. Both src and dst will be altered. Conversion is not nul terminated. */ 217 #define URL_DECODE(dst,src,lim) MB while ((src) < (lim)) \ 218 if ((*(src) == '%') && ((src) < ((lim)-2)) && IS_HEX((src)[1]) && IS_HEX((src)[2])) \ 219 { *((dst)++) = (HEX((src)[1]) << 4) | HEX((src)[2]); (src) += 3; } \ 220 else if (*(src) == '+') { *((dst)++) = ' '; ++(src); } \ 221 else *((dst)++) = *((src)++); ME 222 223 /* Usage: you must set nodes to root prior to calling this macro, for example 224 * v = s->first; REVERSE_LIST_NEXT(s->first, v, vnext); 225 * The nodes argument is "iterator". The reveresed list is left in root. */ 226 #define REVERSE_LIST_NEXT(root,nodes,nxt) MB (root) = 0; \ 227 while (nodes) { void* n = (nodes)->nxt; (nodes)->nxt = (void*)(root); \ 228 (root) = (void*)(nodes); (nodes) = n; } ME 229 230 #define REVERSE_LIST(root,nodes) REVERSE_LIST_NEXT((root),(nodes),next) 231 232 #if 0 233 # define DLIST_ADD(head,x) MB (x)->next = (head).next; /* add to head of doubly linked list */ \ 234 ((x)->prev) = (void*)&(head); \ 235 (head).next->prev = (x); \ 236 (head).next = (x); ME 237 # define DLIST_DEL(prv,nxt) MB (nxt)->prev = (prv); (prv)->next = (nxt); (prv)=(nxt)=0; ME 238 #endif 239 240 #define DPDU_ADD(head,x) MB (x)->g.pdunext = (head).pdunext; /* add to head of doubly linked list */ \ 241 ((x)->g.pduprev) = (void*)&(head); \ 242 (head).pdunext->g.pduprev = (x); \ 243 (head).pdunext = (x); ME 244 245 #define PDU_DLIST_DEL(p) MB (p)->g.pdunext->g.pduprev = (p)->g.pduprev; \ 246 (p)->g.pduprev->g.pdunext = (p)->g.pdunext; \ 247 (p)->g.pduprev = (p)->g.pdunext = 0; ME 248 249 #define PREPEND_LIST(root,list,typ) MB while (list) { \ 250 (typ)* x = (list); (list) = (list)->next; /* remove from list */ \ 251 x->next = (root); (root) = x; /* append at root */ \ 252 } ME 253 254 #define FREE_LIST_NEXT(root,type,nxt) MB type pp; type dead; for (pp = (root); pp; dead = pp, pp = pp->nxt, FREE_EXPR(dead)) ; (root) = 0; ME 255 #define FREE_LIST(root,type) FREE_LIST_NEXT((root),type,next) 256 257 /* Memory management */ 258 259 #define MALLOC(p) CHK_NULL((p)=malloc(sizeof(*(p)))) 260 #define DUP(d,s) MB CHK_NULL((d)=malloc(sizeof(*(s)))); if (d) memcpy((d),(s),sizeof(*(s))); ME 261 #define REALLOC(p) MB if (p) CHK_NULL((p)=realloc((p), sizeof(*p))); \ 262 else CHK_NULL((p)=malloc(sizeof(*(p)))); ME 263 264 #if 0 265 # define MALLOCN(p,n) CHK_NULL((void*)(p)=malloc(n)) 266 # define REALLOCN(p,n) MB if (p) CHK_NULL((void*)(p)=realloc((p),(n))); \ 267 else CHK_NULL((void*)(p)=malloc(n)); ME 268 # define STRDUP(d,s) MB (d) = strdup(s); ME 269 #else 270 /* Catch mallocs of zero size */ 271 # define MALLOCN(p,n) MB ASSERT(n); CHK_NULL((p)=malloc(n)); ME 272 # define REALLOCN(p,n) MB ASSERT(n); if (p) CHK_NULL((p)=realloc((p),(n))); \ 273 else CHK_NULL((p)=malloc(n)); ME 274 # define STRDUP(d,s) MB (d) = strdup(s); ME 275 #endif 276 277 #define DUPN(d,s,n) MB MALLOCN(d,n); if (d) memcpy((d),(s),(n)); ME 278 279 #if 1 280 # define FREE(p) (p) = 0; free(p) 281 # define FREE_EXPR(p) free(p) 282 #else 283 # define FREE(p) 0 284 # define FREE_EXPR(p) (0) 285 #endif 286 287 #define ZERO(p,n) memset((p), 0, (n)) 288 #define ZMALLOC(p) MB MALLOC(p); ZERO((p), sizeof(*(p))); ME 289 #define ZMALLOCN(p,n) MB MALLOCN((p),(n)); ZERO((p), (n)); ME 290 291 /* Common type declarations */ 292 #define const_str const char FAR* 293 #define var_str char FAR* 294 295 /* Hash algorithm cannibalized from perl-5.6.1 hv.h, line 50 296 * register unsigned int h, hh; 297 * SHASH(key,h); 298 * hh = h%hash_size; // convert open ended hash to bounded hash 299 * 300 * SHASH() simply computes openended hash over C string (as opposed to blob) 301 * FIND_SHASH() actually scans into hash table and finds the slot containting 302 * the value 303 */ 304 305 #define SHASH(key,h) MB register CU8* s = (CU8*)(key); (h)=0; \ 306 while (*s) (h) = (h)*33 + *s++; (h) += (h)>>5; ME 307 308 #define FIND_SHASH(key,hh,hash_size,tab) MB register unsigned int h; \ 309 SHASH(key,h); (hh) = h%(hash_size); \ 310 while ((tab)[(hh)] && strcmp((tab)[(hh)], (key))) (hh)++; ME 311 312 /* Same perl hash algorithm for the case where string is fully binary */ 313 314 #define BHASH(key,len,h) MB \ 315 register CU8* s = (CU8*)(key); register int l = (len); (h)=0; \ 316 while (l--) (h) = (h)*33 + *s++; (h) += (h)>>5; ME 317 318 /* Simple pool allocator (only allows you to allocate more). 319 * p = pointer that will receive the memory 320 * k = allocation arena header 321 * n = amount to allocate (negative deallocates, but careful here) 322 * e = function call that will extend the arena, if needed 323 * 324 * PALIGN() effects rounding up so 64 bit alignment is preserved 325 * PALLOCN() allocates memory without regard to possibility of arena ending, 326 * i.e. it assumes the arena was already prextended to the right 327 * size. The arena is assumed to contain field ap (alloc pointer) 328 * which is used to remember the next free location. E.g: 329 * 330 * struct arena { 331 * struct arena* next; // not required, but usually used by extension function 332 * int len; // required by ALLOCMORE() 333 * U8* ap; // next free location (required) 334 * U8 dat[0]; // actual data (as much as len indicates), required by ALLOCMORE() 335 * } 336 * PALLOC() same as PALLOCN(), but takes the amount to alloc from sizeof of the pointed type 337 * 338 * PALLOCEXTN() allocates memory and foresees the possibility that arena has to be 339 * extended. Presumably this is done using linked list of arenas 340 * where newest arena is linked to the head of the list. Typical 341 * call and extension function would be 342 * 343 * PALLOCEXT(p, k, k = more_arena(k, psiz)); // psiz represents byte size of the allocation 344 * PALLOCEXTN(p, k, 100, k = more_arena(k, psiz)); // here size is 100 345 * 346 * struct arena* 347 * more_arena(struct arena* k, int n) { 348 * struct arena* kk; 349 * MALLOCN(kk, sizeof(struct arena) + ALIGN(n)); // or allocate more at once 350 * kk->next = k; 351 * kk->len = ALIGN(n); // or more 352 * kk->ap = kk->dat; 353 * return kk; 354 * } 355 * PALLOCEXT() same as PALLOCEXTN() but determines the size of the arena from sizeof of the pointed type 356 */ 357 358 /*#define ALIGN32(n) ((((unsigned)(n)-1)&0xfffffffc)+4)*/ 359 /*#define ALIGN64(n) ((((unsigned)(n)-1)&0xfffffff8)+8)*/ 360 #define ALIGN16(n) (((n) + 0x1) & ~0x1) 361 #define ALIGN32(n) (((n) + 0x3) & ~0x3) 362 #define ALIGN64(n) (((n) + 0x7) & ~0x7) 363 #define ALIGN128(n) (((n) + 0xf) & ~0xf) 364 365 #define PALIGN(n) ALIGN32(n) 366 #define PALLOC(p,k) PALLOCN((p),(k),sizeof(*(p))) 367 #define PALLOCN(p,k,n) MB ((U8*)(p))=(k)->ap; (k)->ap += PALIGN(n); ME 368 #define PALLOCEXT(p,k,e) PALLOCEXTN((p),(k),sizeof(*(p)),(e)) 369 370 /* N.B. PALLOCEXTN() produces compile error about "non-lvalue in assignment" 371 * if p is of type char* (used to happen with U8*). This is either a 372 * compiler bug or me not understanding how C is supposed to work. The 373 * culprit is the assignment `(char*)(p)=(char*)((k)->ap);' 374 * Following C fragment should illustrate the problem 375 * struct kk { char* ap; }; void main() { struct kk* k; char* p; (char*)p = k->ap; } 376 * but fails to reproduce it :-( --Sampo */ 377 #define PALLOCEXTN(p,k,n,e) MB if ((int) ((((char*)((k)->ap))-((char*)((k)->dat))) + (n)) \ 378 > (int) (k)->len) \ 379 { int psiz = (n); if(!(e)) { (p)=0; break; } } \ 380 (char*)(p)=(char*)((k)->ap); (k)->ap += PALIGN(n); ME 381 382 #define ZPALLOC(p,k) MB PALLOC((p),(k)); ZERO((p), sizeof(*(p))); ME 383 #define ZPALLOCN(p,k,n) MB PALLOCN((p),(k),(n)); ZERO((p), (n)); ME 384 #define ZPALLOCEXT(p,k,e) MB PALLOCEXT((p),(k),(e)); ZERO((p), sizeof(*(p))); ME 385 #define ZPALLOCEXTN(p,k,n,e) MB PALLOCEXTN((p),(k),(n),(e)); ZERO((p), (n)); ME 386 387 /* =============== Console color =============== */ 388 /* vt100 terminal color escapes to liven up debug prints :-) 389 * See https://wiki.archlinux.org/index.php/Color_Bash_Prompt */ 390 391 #ifdef NOCOLOR 392 #define CC_RED(x) x 393 #define CC_REDB(x) x 394 #define CC_YELB(x) x 395 #define CC_GRNB(x) x 396 #define CC_BLUB(x) x 397 #define CC_PURB(x) x 398 #define CC_CYNB(x) x 399 #define CC_REDY(x) x 400 #define CC_YELY(x) x 401 #define CC_GREENY(x) x 402 #define CC_BLUY(x) x 403 #define CC_PURY(x) x 404 #define CC_CYNY(x) x 405 #else 406 #define CC_RED(x) "\e[0;31m" x "\e[0m" /* regular red */ 407 #define CC_REDB(x) "\e[1;31m" x "\e[0m" /* bold red */ 408 #define CC_YELB(x) "\e[1;33m" x "\e[0m" 409 #define CC_GRNB(x) "\e[1;32m" x "\e[0m" 410 #define CC_BLUB(x) "\e[1;34m" x "\e[0m" 411 #define CC_PURB(x) "\e[1;35m" x "\e[0m" 412 #define CC_CYNB(x) "\e[1;36m" x "\e[0m" 413 #define CC_REDY(x) "\e[41m" x "\e[0m" /* red background, black text (no bold) */ 414 #define CC_YELY(x) "\e[43m" x "\e[0m" 415 #define CC_GREENY(x) "\e[42m" x "\e[0m" 416 #define CC_BLUY(x) "\e[44m" x "\e[0m" 417 #define CC_PURY(x) "\e[45m" x "\e[0m" 418 #define CC_CYNY(x) "\e[46m" x "\e[0m" 419 #endif 420 421 /* =============== Debugging macro system =============== */ 422 423 #ifndef ERRMAC_INSTANCE 424 /*#define ERRMAC_INSTANCE "\tzx"*/ 425 #define ERRMAC_INSTANCE errmac_instance 426 extern char errmac_instance[64]; 427 #endif 428 429 #define ERRMAC_DEBUG_MASK 0x03 /* 0 = no debug, 1=minimal info debug, 2=bit more, 3=lot more */ 430 #define ERRMAC_XMLDBG 0x04 431 #define ERRMAC_RESERVED 0x08 432 #define ERRMAC_INOUT 0x10 433 #define MOD_AUTH_SAML_INOUT 0x20 434 #define CURL_INOUT 0x40 /* Back Channel */ 435 436 extern int errmac_debug; /* Defined in zxidlib.c */ 437 extern char errmac_indent[256]; /* Defined in zxidlib.c *** Locking issues? */ 438 extern FILE* errmac_debug_log; /* Defined in zxidlib.c as 0 alias to stderr */ 439 #define ERRMAC_DEBUG_LOG (errmac_debug_log?errmac_debug_log:(stderr)) 440 #if 1 441 /* In some scenarios multithreaded access can cause errmac_indent to be scrambled. 442 * However, it should not under- or overflow. Thus no lock. */ 443 #define D_INDENT(s) strncat(errmac_indent, (s), sizeof(errmac_indent)-1) 444 #define D_DEDENT(s) (errmac_indent[MAX(0, strlen(errmac_indent)-sizeof(s)+1)] = 0) 445 #else 446 #define D_INDENT(s) /* no locking issues */ 447 #define D_DEDENT(s) 448 #endif 449 450 #ifdef VERBOSE 451 # define D(format,...) (void)((fprintf(ERRMAC_DEBUG_LOG, "%d %10s:%-3d %-16s %s d %s" format "\n", getpid(), __FILE__, __LINE__, __FUNCTION__, ERRMAC_INSTANCE, errmac_indent, ## __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG))) 452 # define DD D 453 #else 454 # ifdef USE_PTHREAD 455 # ifdef USE_AKBOX_FN 456 # define D(format,...) (void)((errmac_debug&ERRMAC_DEBUG_MASK)>1 && (fprintf(ERRMAC_DEBUG_LOG, "%d.%lx %04x:%-4d %s d %s" format "\n", getpid(), (long)pthread_self(), AKBOX_FN(__FUNCTION__), __LINE__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG))) 457 # else 458 # define D(format,...) (void)((errmac_debug&ERRMAC_DEBUG_MASK)>1 && (fprintf(ERRMAC_DEBUG_LOG, "%d.%lx %10s:%-3d %-16s %s d %s" format "\n", getpid(), (long)pthread_self(), __FILE__, __LINE__, __FUNCTION__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG))) 459 # endif 460 # else 461 # define D(format,...) (void)((errmac_debug&ERRMAC_DEBUG_MASK)>1 && (fprintf(ERRMAC_DEBUG_LOG, "%d %10s:%-3d %-16s %s d %s" format "\n", getpid(), __FILE__, __LINE__, __FUNCTION__, ERRMAC_INSTANCE, errmac_indent, ## __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG))) 462 # endif 463 # define DD(format,...) /* Documentative */ 464 #endif 465 466 #ifdef USE_PTHREAD 467 # ifdef USE_AKBOX_FN 468 # define ERR(format,...) (fprintf(ERRMAC_DEBUG_LOG, "%d.%lx %04x:%-4d %s E %s" format "\n", getpid(), (long)pthread_self(), AKBOX_FN(__FUNCTION__), __LINE__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG)) 469 # define WARN(format,...) (fprintf(ERRMAC_DEBUG_LOG, "%d.%lx %04x:%-4d %s W %s" format "\n", getpid(), (long)pthread_self(), AKBOX_FN(__FUNCTION__), __LINE__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG)) 470 # define INFO(format,...) (void)(errmac_debug&ERRMAC_DEBUG_MASK && (fprintf(ERRMAC_DEBUG_LOG, "%d.%lx %04x:%-4d %s I %s" format "\n", getpid(), (long)pthread_self(), AKBOX_FN(__FUNCTION__), __LINE__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG))) 471 # else 472 # define ERR(format,...) (fprintf(ERRMAC_DEBUG_LOG, "%d.%lx %10s:%-3d %-16s %s E %s" format "\n", getpid(), (long)pthread_self(), __FILE__, __LINE__, __FUNCTION__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG)) 473 # define WARN(format,...) (fprintf(ERRMAC_DEBUG_LOG, "%d.%lx %10s:%-3d %-16s %s W %s" format "\n", getpid(), (long)pthread_self(), __FILE__, __LINE__, __FUNCTION__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG)) 474 # define INFO(format,...) (void)(errmac_debug&ERRMAC_DEBUG_MASK && (fprintf(ERRMAC_DEBUG_LOG, "%d.%lx %10s:%-3d %-16s %s I %s" format "\n", getpid(), (long)pthread_self(), __FILE__, __LINE__, __FUNCTION__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG))) 475 # endif 476 #else 477 # define ERR(format,...) (fprintf(ERRMAC_DEBUG_LOG, "%d %10s:%-3d %-16s %s E %s" format "\n", getpid(), __FILE__, __LINE__, __FUNCTION__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG)) 478 # define WARN(format,...) (fprintf(ERRMAC_DEBUG_LOG, "%d %10s:%-3d %-16s %s W %s" format "\n", getpid(), __FILE__, __LINE__, __FUNCTION__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG)) 479 # define INFO(format,...) (void)(errmac_debug&ERRMAC_DEBUG_MASK && (fprintf(ERRMAC_DEBUG_LOG, "%d %10s:%-3d %-16s %s I %s" format "\n", getpid(), __FILE__, __LINE__, __FUNCTION__, ERRMAC_INSTANCE, errmac_indent, __VA_ARGS__), fflush(ERRMAC_DEBUG_LOG))) 480 #endif 481 482 #define D_XML_BLOB(cf, lk, len, xml) errmac_debug_xml_blob((cf), __FILE__, __LINE__, __FUNCTION__, (lk), (len), (xml)) 483 #define DD_XML_BLOB(cf, lk, len, xml) /* Documentative */ 484 485 int hexdmp(const char* msg, const void* p, int len, int max); 486 int myhexdump(const char* msg, const void* p, const void* lim, int max); 487 488 #define HEXDUMP(msg, p, lim, max) if ((errmac_debug&ERRMAC_DEBUG_MASK) > 1) myhexdump((msg), (p), (lim), (max)) 489 #define DHEXDUMP(msg, p, lim, max) /* Disabled hex dump */ 490 491 #define DUMP_CORE() ASSERT(0) 492 #define NEVER(explanation,val) D(explanation,(val)) 493 #define NEVERNEVER(explanation,val) MB ERR(explanation,(val)); fflush(stdout); fflush(ERRMAC_DEBUG_LOG); DUMP_CORE(); ME 494 495 #define CMDLINE(x) 496 497 #ifdef DEBUG 498 #define DEFINE_MUTEX_INFO(name) 499 /*#define DEFINE_MUTEX_INFO(name) char* name ## info; int name ## line; pthread_t name ## thr;*/ 500 #define SET_MUTEX_INFO(name, msg) 501 /*#define SET_MUTEX_INFO(name, msg) name ## info = __FILE__ " " msg; name ## line = __LINE__; name ## thr = pthread_self();*/ 502 # ifdef STDOUT_DEBUG 503 # define LOG ERRMAC_DEBUG_LOG, 504 # define OPEN_LOG() 505 # define CLOSE_LOG() 506 # define FLUSH() fflush(stdout) 507 # else 508 # define LOG ERRMAC_DEBUG_LOG, 509 # define LOG_FILE HOME "foo.log" 510 # define OPEN_LOG() MB TR { if ((errmac_debug_log = fopen(LOG_FILE, "a")) == NULL) trace = 0; } ME 511 # define CLOSE_LOG() MB TR if (errmac_debug_log) { fclose(errmac_debug_log); debug_log=0; trace = 0; } ME 512 # define FLUSH() MB if (errmac_debug_log) fflush(errmac_debug_log); ME 513 # endif 514 515 #define TR if (trace) 516 #define TR2 if (trace > 1) 517 #define TR3 if (trace > 2) 518 #define PR fprintf 519 #define DUMP(x) dump(LOG (char*)&(x), sizeof(x)) 520 #define PRMEM(f,buf,len) MB char b[256]; memcpy(b, (buf), MIN(256, (len))); \ 521 PR(LOG (f), b, (len)); ME 522 523 #else 524 /* -------------------------------------------------------- */ 525 /* Nondebugging macros */ 526 527 #define DEFINE_MUTEX_INFO(name) 528 #define SET_MUTEX_INFO(name, msg) 529 #define OPEN_LOG() 530 #define CLOSE_LOG() 531 # ifdef STDOUT_DEBUG 532 # define LOG ERRMAC_DEBUG_LOG, 533 # define FLUSH() fflush(errmac_debug_log) 534 # else 535 536 /* N.B. these macros assume existence of global variable debug_log, unless STDOUT_DEBUG 537 * is defined. */ 538 # define LOG ERRMAC_DEBUG_LOG, 539 # define FLUSH() fflush(errmac_debug_log) 540 # endif 541 #define PR fprintf 542 #define PRMEM(f,buf,len) MB char b[256]; memcpy(b, (buf), MIN(254, (len))); \ 543 b[MIN(255, (len))] = '\0'; PR(LOG (f), b, (len)); ME 544 #ifndef FLUSH 545 # define FLUSH() 546 #endif 547 #define TR if (0) 548 #define TR2 if (0) 549 #define TR3 if (0) 550 #define DUMP(x) 551 552 #endif 553 554 #ifdef DEBUG 555 556 /* Try to produce some exception, unless global setting says asserting is NOT ok. */ 557 558 extern char* assert_msg; 559 //#define DIE_ACTION(b) MB fprintf(ERRMAC_DEBUG_LOG, assert_msg, ERRMAC_INSTANCE); if (assert_nonfatal == 0) { *((int*)0xffffffff) = 1; } ME 560 #define DIE_ACTION(b) MB fprintf(ERRMAC_DEBUG_LOG, assert_msg, ERRMAC_INSTANCE); if (assert_nonfatal == 0) { *((int*)-1) = 1; } ME 561 562 /* Many development time sanity checks use these macros so that they 563 * can be compiled away from the final version. ASSERT macros are more 564 * convenient than their library counter parts, such as assert(3), in 565 * that core is dumped in the function where the ASSERT fired, rather 566 * than somewhere deep inside a library. N.B. Since these are macros, 567 * any arguments may get evaluated zero or more times, producing no, 568 * one, or multiple side effects, depending on 569 * circumstances. Therefore arguments, should NOT have any side 570 * effects. Otherwise "Heisenbugs" will result that manifest depending 571 * on whether ASSERTs are enabled or not. */ 572 573 #if 1 /* More verbose versions */ 574 # define CHK(cond,err) MB if ((cond)) { \ 575 /*ak_ts(AK_NFN(__FUNCTION__), __LINE__, AK_ASSERT_RAZ, "CHK FAIL: " #cond, "");*/ \ 576 ERR("CHK FAIL: " #cond " %x", err); \ 577 DIE_ACTION(err); } ME 578 579 # define ASSERT(c) MB if (!(c)) { \ 580 /*ak_ts(AK_NFN(__FUNCTION__), __LINE__,AK_ASSERT_RAZ,(char*)(int)(a),"ASSERT FAIL: " #c);*/ \ 581 ERR("ASSERT FAIL: " #c " %d", 0); \ 582 DIE_ACTION(1); } ME 583 584 # define ASSERTOP(a,op,b,err) MB if (!((a) op (b))) { \ 585 /*ak_ts(AK_NFN(__FUNCTION__), __LINE__, AK_ASSERTOP_RAZ, (char*)(int)(a), "ASSERTOP FAIL: " #a #op #b);*/ \ 586 ERR("ASSERTOP FAIL: " #a #op #b " %x", (int)(err)); \ 587 DIE_ACTION(1); } ME 588 589 # define ASSERTOPI(a,op,b) MB if (!((a) op (b))) { \ 590 /*ak_ts(AK_NFN(__FUNCTION__), __LINE__, AK_ASSERTOP_RAZ, (char*)(int)(a), "ASSERTOP FAIL: " #a #op #b);*/ \ 591 ERR("ASSERTOP FAIL: " #a #op #b " %x", (int)(a)); \ 592 DIE_ACTION(1); } ME 593 594 # define ASSERTOPL(a,op,b) MB if (!((a) op (b))) { \ 595 /*ak_ts(AK_NFN(__FUNCTION__), __LINE__, AK_ASSERTOP_RAZ, (char*)(int)(a), "ASSERTOP FAIL: " #a #op #b);*/ \ 596 ERR("ASSERTOP FAIL: " #a #op #b " %lx", (long)(a)); \ 597 DIE_ACTION(1); } ME 598 599 # define ASSERTOPP(a,op,b) MB if (!((a) op (b))) { \ 600 /*ak_ts(AK_NFN(__FUNCTION__), __LINE__, AK_ASSERTOP_RAZ, (char*)(int)(a), "ASSERTOP FAIL: " #a #op #b);*/ \ 601 ERR("ASSERTOPP FAIL: " #a #op #b " %p", (a)); \ 602 DIE_ACTION(1); } ME 603 604 # define FAIL(x,why) MB /*ak_ts(AK_NFN(__FUNCTION__), __LINE__, AK_FAIL_RAZ, (char*)(x), why);*/ DIE_ACTION(1); ME 605 606 /* SANITY_CHK is a smaller assert which checks a condition but will not force an abort */ 607 # define SANITY_CHK(cond,...) MB if (!(cond)) \ 608 /*ak_tsf(AK_NFN(__FUNCTION__), __LINE__, AK_SANITY_RAZ, #cond, __VA_ARGS__);*/ 1; ME 609 #else /* More sterile versions */ 610 # define CHK(cond,err) MB if (cond) { DIE_ACTION(err); } ME 611 # define ASSERT(c) MB if (!(c)) { DIE_ACTION(1); } ME 612 # define ASSERTOP(a,op,b,err) MB if (!((a) op (b))) { DIE_ACTION(err); } ME 613 # define ASSERTOPI(a,op,b) MB if (!((a) op (b))) { DIE_ACTION(1); } ME 614 # define ASSERTOPL(a,op,b) MB if (!((a) op (b))) { DIE_ACTION(1); } ME 615 # define ASSERTOPP(a,op,b) MB if (!((a) op (b))) { DIE_ACTION(1); } ME 616 # define FAIL(x,why) MB DIE_ACTION(1); ME 617 # define SANITY_CHK(cond,...) MB if (!(cond)) NEVER("insanity %d",0); ME 618 #endif 619 620 /* Sometimes compiler issues bogus "variable might be uninitialized" 621 * warnings. To silence them, use this macro thusly 622 * char* yourvar BOGUS_UNINITIALIZED_WARNING_0; */ 623 #define BOGUS_UNINITIALIZED_WARNING_0 =0 624 625 #else /* ---------------- no debug --------------- */ 626 # define CHK(cond,err) 627 # define ASSERT(c) 628 # define ASSERTOP(a,op,b,err) 629 # define ASSERTOPI(a,op,b) 630 # define ASSERTOPL(a,op,b) 631 # define ASSERTOPP(a,op,b) 632 # define FAIL(format) 633 # define BOGUS_UNINITIALIZED_WARNING_0 634 #endif /* DEBUG */ 635 636 /* -------------------------------------------------------- */ 637 /* Asserting and sanity checks */ 638 639 #define CHK_NULL(n) ASSERT((intptr_t)(n)) 640 #define CHK_ERRNO(n) CHK(((n)<0), errno) 641 #define CHK_MAGIC(p,m) MB ASSERT(p); ASSERTOP((p)->magic, ==, (m), (p)->magic); ME 642 643 #define ASSERT_THR(t) ASSERTOP(pthread_self(), ==, (t), (t)) 644 /* Following macro assumes that each lock is accompanied by a variable 645 * describing who holds it. This macro takes that variable as an 646 * argument (e.g. shuff_locked). */ 647 #define ASSERT_NOT_IN_LOCK(t) ASSERT((unsigned)(t) != (unsigned)pthread_self()) 648 #define ASSERT_IN_LOCK(t) ASSERTOP((unsigned)(t), ==, (unsigned)pthread_self(),(t)) 649 650 /* DASSERT family is "documentative" assert, i.e. not compiled in even in debug mode */ 651 #define DASSERT(c) 652 #define DASSERTOP(a,op,b,err) 653 #define DASSERTOPI(a,op,b) 654 #define DASSERTOPL(a,op,b) 655 #define DASSERTOPP(a,op,b) 656 #define DASSERT_THR(t) 657 #define DASSERT_NOT_IN_LOCK(t) 658 #define DASSERT_IN_LOCK(t) 659 660 #ifdef MUTEX_DEBUG 661 # define MUTEX_INITIALIZER PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP 662 # define MUTEXATTR &debug_mutexattr 663 #else 664 # define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 665 # define MUTEXATTR 0 666 #endif 667 #define MUTEXATTR_DECL debug_mutexattr 668 669 /* =============== pthread locking =============== */ 670 671 #ifdef USE_PTHREAD 672 # if 1 673 /*#define LOCK_STATIC(l) pthread_mutex_t l.ptmut = PTHREAD_MUTEX_INITIALIZER do not use */ 674 # define LOCK_INIT(l) pthread_mutex_init(&(l).ptmut, 0) 675 # define LOCK(l,lk) MB if (pthread_mutex_lock(&(l).ptmut)) NEVERNEVER("DEADLOCK(%s)", (lk)); (l).func = __FUNCTION__; (l).line = __LINE__; (l).thr = pthread_self(); ME 676 # define UNLOCK(l,lk) MB ASSERTOPL((long)((l).thr), ==, (long)pthread_self()); /*(l).func = __FUNCTION__; (l).line = __LINE__;*/ (l).thr = 0; if (pthread_mutex_unlock(&(l).ptmut)) NEVERNEVER("UNLOCK-ERR(%s)", (lk)); ME 677 /* pthread_cond_wait(3) does some important magic: it unlocks the mutex (l) 678 * so that other threads may move. But it will reacquire the lock before 679 * returning. Due to this, other threads may have set lock debugging variables, 680 * so we need to reset them back here. */ 681 # define ERRMAC_COND_WAIT(c,l,lk) MB pthread_cond_wait((c), &(l).ptmut); (l).func = __FUNCTION__; (l).line = __LINE__; (l).thr = pthread_self(); ME 682 # define ERRMAC_COND_SIG(c,lk) pthread_cond_signal(c) 683 # else 684 /*#define LOCK_STATIC(l) pthread_mutex_t l = PTHREAD_MUTEX_INITIALIZER do not use */ 685 # define LOCK_INIT(l) pthread_mutex_init(&(l), 0) 686 # define LOCK(l,lk) if (pthread_mutex_lock(&(l))) NEVERNEVER("DEADLOCK(%s)", (lk)) 687 # define UNLOCK(l,lk) if (pthread_mutex_unlock(&(l))) NEVERNEVER("UNLOCK-TWICE(%s)", (lk)) 688 # define ERRMAC_COND_WAIT(c,l,lk) pthread_cond_wait((c), &(l).ptmut) 689 # define ERRMAC_COND_SIG(c,lk) pthread_cond_signal(c) 690 # endif 691 #else 692 # define LOCK_STATIC(l) 693 # define LOCK_INIT(l) 694 # define LOCK(l,lk) 695 # define UNLOCK(l,lk) 696 # define ERRMAC_COND_WAIT(c,l,lk) NEVERNEVER("Program written to use pthread_cond_wait() can not work when compiled to not use it (%s).",(lk)); 697 # define ERRMAC_COND_SIG(c,lk) NEVERNEVER("Program written to use pthread_cond_sig() can not work when compiled to not use it (%s).",(lk)); 698 #endif 699 700 /* =============== file system flocking =============== */ 701 702 #ifndef USE_LOCK 703 #if 0 704 #define FLOCKEX(fd) lockf((fd), F_LOCK, 1) 705 #define FUNLOCK(fd) lockf((fd), F_ULOCK, 1) 706 #else 707 #define FLOCKEX(fd) fcntl((fd), F_SETLKW, &errmac_rdlk) 708 #define FUNLOCK(fd) fcntl((fd), F_SETLKW, &errmac_unlk) 709 #endif 710 #else 711 /* If you have neither flock() nor lockf(), then -DUSE-LOCK=dummy_no_flock 712 * but beware that this means NO file locking will be done, possibly 713 * leading to corrupt audit logs, or other files. You need to judge 714 * the probability of this happening as well as the cost of clean-up. */ 715 #define dummy_no_flock(x,y) (0) /* no file locking where locking should be */ 716 #define FLOCKEX(fd) USE_LOCK((fd), LOCK_EX) 717 #define FUNLOCK(fd) USE_LOCK((fd), LOCK_UN) 718 #endif 719 720 /* Nibble and bit arrays */ 721 722 #define GET_NIBBLE(b, i) ((i) & 0x01 ? (b)[(i)>>1] & 0x0f : ((b)[(i)>>1] >> 4) & 0x0f ) 723 #define SET_NIBBLE(b, i, v) ((i) & 0x01 ? ((b)[(i)>>1] = (b)[(i)>>1] & 0xf0 | (v) & 0x0f) \ 724 : ((b)[(i)>>1] = (b)[(i)>>1] & 0x0f | ((v) << 4) & 0xf) ) 725 726 #define GET_BIT(a,i) ((a)[(i) >> 3] & (1 << ((i) & 0x3))) 727 #define SET_BIT(a,i,v) ((a)[(i) >> 3] = (v) ? ((a)[(i) >> 3] | (1 << ((i) & 0x3))) : ((a)[(i) >> 3] & ~(1 << ((i) & 0x3)))) 728 729 /* -------------------------------------------------------- */ 730 /* BER and ASN.1 Macros */ 731 732 /* Decode the BER extensible integer format (i.e. that which represents 733 * numbers in base128 with high bit indicating continuation. 734 */ 735 736 /* #define BER_INT(p,x) MB (x) = *((p)++); if ((x)&0x80) { (x)&=0x7f;\ */ 737 /* do { (x) = ((x)<<7) | ((CU8)(*(p)) & 0x7f); \ */ 738 /* } while (*((p)++)&0x80) } ME */ 739 740 /* #define BER_INT_N(p,x,n) MB if (n) { (x) = *((p)++); \ */ 741 /* if ((x)&0x80 && --(n)) { \ */ 742 /* (x)&=0x7f; \ */ 743 /* do { (x) = ((x)<<7) | (((CU8)(*(p))) & 0x7f); \ */ 744 /* } while (*((p)++)&0x80 && --(n)); \ */ 745 /* }} else { (x) = 0; } ME */ 746 747 #if 0 748 /* *** This code is wrong. Please see pdu/bermacros.h for macro that works. */ 749 #define BER_INT_N(p,x,n) MB { (x) = *((p)++); \ 750 { switch((n)) {\ 751 case 0: (x) = 0; break \ 752 case 1: (x) = *((p)++) & 0x7f; break; \ 753 case 2: (x) = ((*(p)<<8) | *((p)+1)) | 0x7fff); (p)+=2; break; \ 754 case 3: (x) = ((*(p)<<16) | (*((p)+1)<<8) | *((p)+2)) | 0x7fffff; (p)+=3; break; \ 755 case 4: (x) = ((*(p)<<24) | (*((p)+1)<<16) | (*((p)+2)<<8) | *((p)+3)) | 0x7fffffff; (p)+=4; break; \ 756 default: NEVER("BER_LEN: long length > 4 not supported (%d)",(x)); \ 757 }} ME 758 #endif 759 760 #define BER_LEN(p,x) MB (x) = *((p)++); if ((x)&0x80) { switch((x)&0x7f) {\ 761 case 0: NEVER((LOG "BER_LEN: long length is zero?!?")); break; \ 762 case 1: (x) = *((p)++); break; \ 763 case 2: (x) = (*(p)<<8) | *((p)+1); (p)+=2; break; \ 764 case 3: (x) = (*(p)<<16) | (*((p)+1)<<8) | *((p)+2); (p)+=3; break; \ 765 case 4: (x) = (*(p)<<24) | (*((p)+1)<<16) | (*((p)+2)<<8) | *((p)+3); (p)+=4; break; \ 766 default: NEVER("BER_LEN: long length > 4 not supported (%d)",(x)); \ 767 }} ME 768 769 /* Encode a TAG in BER (only checked for unsigned ints) 770 * (This was formerly called BER_UINT_WRITE, but BER integers are encoded 771 * differently than BER Tags) 772 */ 773 774 #define BER_TAG_WRITE(p,x) MB if ((x) < (1<<7)) { *((p)++) = (U8)(x); } \ 775 else if ((x) < (1<<14)) { *((p)++) = 0x80 | (((x)>>7) & 0x7f); \ 776 *((p)++) = (x) & 0x7f;} \ 777 else if ((x) < (1<<21)) { *((p)++) = 0x80 | (((x)>>14) & 0x7f); \ 778 *((p)++) = 0x80 | (((x)>>7) & 0x7f); \ 779 *((p)++) = (x) & 0x7f;} \ 780 else if ((x) < (1<<28)) { *((p)++) = 0x80 | (((x)>>21) & 0x7f); \ 781 *((p)++) = 0x80 | (((x)>>14) & 0x7f); \ 782 *((p)++) = 0x80 | (((x)>>7) & 0x7f); \ 783 *((p)++) = (x) & 0x7f;} \ 784 else { NEVER("int %d too big to encode in BER\n",(x)); }; ME 785 786 /* Encode an int in BER (only checked for unsigned ints) */ 787 788 #define BER_UINT_WRITE(p,x) MB if ((x) <= 0x7f) { *((p)++) = (U8)(x); } \ 789 else if ((x) <= 0x7fff) { *((p)++) = ((x) >> 8) & 0xff; \ 790 *((p)++) = (x); } \ 791 else if ((x) <= 0x7fffff) { *((p)++) = ((x) >> 16) & 0xff; \ 792 *((p)++) = ((x) >> 8) & 0xff; \ 793 *((p)++) = (x) & 0xff; } \ 794 else if ((x) <= 0x7fffffff) { *((p)++) = ((x) >> 24) & 0xff; \ 795 *((p)++) = ((x) >> 16) & 0xff; \ 796 *((p)++) = ((x) >> 8) & 0xff; \ 797 *((p)++) = (x) & 0xff; } \ 798 else { NEVER("length %lx too big to encode in BERLEN\n",(unsigned long)(x)); }; ME 799 800 /* Encode length in BER */ 801 802 #define BER_LEN_WRITE(p,x) MB if ((x) <= 0x7f) { *((p)++) = (U8)(x); } \ 803 else if ((x) <= 255U) { *((p)++) = 0x81; *((p)++) = (U8)(x); } \ 804 else if ((x) <= 65535U) { *((p)++) = 0x82; \ 805 *((p)++) = ((x) >> 8) & 0xff; \ 806 *((p)++) = (x) & 0xff; } \ 807 else if ((x) <= 16777215U) { *((p)++) = 0x83; \ 808 *((p)++) = ((x) >> 16) & 0xff; \ 809 *((p)++) = ((x) >> 8) & 0xff; \ 810 *((p)++) = (x) & 0xff; } \ 811 else if ((x) <= 4294967295U) { *((p)++) = 0x84; \ 812 *((p)++) = ((x) >> 24) & 0xff; \ 813 *((p)++) = ((x) >> 16) & 0xff; \ 814 *((p)++) = ((x) >> 8) & 0xff; \ 815 *((p)++) = (x) & 0xff; } \ 816 else { NEVER("length %d too big to encode in BERLEN\n",(x)); }; ME 817 818 #define PEM_CERT_START "-----BEGIN CERTIFICATE-----" 819 #define PEM_CERT_END "-----END CERTIFICATE-----" 820 #define PEM_RSA_PRIV_KEY_START "-----BEGIN RSA PRIVATE KEY-----" 821 #define PEM_RSA_PRIV_KEY_END "-----END RSA PRIVATE KEY-----" 822 #define PEM_DSA_PRIV_KEY_START "-----BEGIN DSA PRIVATE KEY-----" 823 #define PEM_DSA_PRIV_KEY_END "-----END DSA PRIVATE KEY-----" 824 #define PEM_PRIV_KEY_START "-----BEGIN PRIVATE KEY-----" 825 #define PEM_PRIV_KEY_END "-----END PRIVATE KEY-----" 826 827 /* Define this so it results CR (0xd) and LF (0xa) on your platform. N.B. \n is not always 0xa! */ 828 #define CRLF "\015\012" 829 #define CRLF2 CRLF CRLF 830 831 /* Both methods are valid for booleans, but the default "1" and "0" approach is more compact. 832 * If you have to interop with buggy software that insists on the "true" and "false", 833 * tweak this conditional. */ 834 835 #ifdef XML_BOOL_WASTE_SPACE 836 #define XML_TRUE "true" 837 #define XML_FALSE "false" 838 #else 839 #define XML_TRUE "1" 840 #define XML_FALSE "0" 841 #endif 842 843 /* Test XML boolean field (zx_str) for XML valid "true" values */ 844 #define XML_TRUE_TEST(x) ((x) && (x)->s && (((x)->len == 1 && (x)->s[0] == '1') || ((x)->len == 4 && !memcmp((x)->s, "true", 4)))) 845 846 void platform_broken_snprintf(int n, const char* where, int maxlen, const char* fmt); 847 848 #if 0 849 /* Following come handy when printf(3) is broken or otherwise 850 * the libc support is minimal. */ 851 852 static char* errhexll(const char* prefix, long long x) { 853 static char buf[64]; 854 char const digit[] = "0123456789abcdef"; 855 char* p; 856 int i; 857 for (p = buf; prefix && *prefix; ++prefix, ++p) *p = *prefix; 858 #if 0 859 *p++ = digit[(x >> 60) & 0x0f]; 860 *p++ = digit[(x >> 56) & 0x0f]; 861 *p++ = digit[(x >> 52) & 0x0f]; 862 *p++ = digit[(x >> 48) & 0x0f]; 863 *p++ = digit[(x >> 44) & 0x0f]; 864 *p++ = digit[(x >> 40) & 0x0f]; 865 *p++ = digit[(x >> 36) & 0x0f]; 866 *p++ = digit[(x >> 32) & 0x0f]; 867 868 *p++ = digit[(x >> 28) & 0x0f]; 869 *p++ = digit[(x >> 24) & 0x0f]; 870 *p++ = digit[(x >> 20) & 0x0f]; 871 *p++ = digit[(x >> 16) & 0x0f]; 872 *p++ = digit[(x >> 12) & 0x0f]; 873 *p++ = digit[(x >> 8) & 0x0f]; 874 *p++ = digit[(x >> 4) & 0x0f]; 875 *p++ = digit[x & 0x0f]; 876 *p++ = '\n'; 877 write(1, buf, p-buf); 878 #else 879 p+=8; 880 *p-- = '\n'; 881 for (i=8; i; --i, x >>= 4) *p-- = digit[x & 0x0f]; 882 write(1, buf, p+9-buf); 883 #endif 884 return buf; 885 } 886 887 static char* errstr(const char* prefix, const char* str, int len) { 888 static char buf[64]; 889 char* p; 890 int i; 891 for (p = buf; prefix && *prefix; ++prefix, ++p) *p = *prefix; 892 if (len == -2) 893 len = strlen(str); 894 for (; str && *str && len && p < buf+sizeof(buf)-1; --len) *p++ = *str++; 895 *p++ = '\n'; 896 write(1, buf, p-buf); 897 return buf; 898 } 899 #endif 900 901 #endif /* errmac.h */ 902