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