d1896e7f8f156180d430a433491598cf70d54b38
[krb5.git] / src / include / k5-platform.h
1 /* -*- mode: c; indent-tabs-mode: nil -*- */
2 /* include/k5-platform.h */
3 /*
4  * Copyright 2003, 2004, 2005, 2007, 2008, 2009 Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  *
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  Furthermore if you modify this software you must label
20  * your software as modified software and not distribute it in such a
21  * fashion that it might be confused with the original M.I.T. software.
22  * M.I.T. makes no representations about the suitability of
23  * this software for any purpose.  It is provided "as is" without express
24  * or implied warranty.
25  */
26
27 /*
28  * Some platform-dependent definitions to sync up the C support level.
29  * Some to a C99-ish level, some related utility code.
30  *
31  * Currently:
32  * + [u]int{8,16,32}_t types
33  * + 64-bit types and load/store code
34  * + SIZE_MAX
35  * + shared library init/fini hooks
36  * + consistent getpwnam/getpwuid interfaces
37  * + va_copy fudged if not provided
38  * + strlcpy/strlcat
39  * + fnmatch
40  * + [v]asprintf
41  * + mkstemp
42  * + zap (support function; macro is in k5-int.h)
43  * + path manipulation
44  * + _, N_, dgettext, bindtextdomain, setlocale (for localization)
45  */
46
47 #ifndef K5_PLATFORM_H
48 #define K5_PLATFORM_H
49
50 #include "autoconf.h"
51 #include <assert.h>
52 #include <string.h>
53 #include <stdarg.h>
54 #include <limits.h>
55 #include <stdlib.h>
56 #include <stdio.h>
57 #include <fcntl.h>
58 #include <errno.h>
59 #ifdef HAVE_FNMATCH_H
60 #include <fnmatch.h>
61 #endif
62
63 #ifdef _WIN32
64 #define CAN_COPY_VA_LIST
65 #endif
66
67 #if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
68 #include <TargetConditionals.h>
69 #endif
70
71 /* Initialization and finalization function support for libraries.
72
73    At top level, before the functions are defined or even declared:
74    MAKE_INIT_FUNCTION(init_fn);
75    MAKE_FINI_FUNCTION(fini_fn);
76    Then:
77    int init_fn(void) { ... }
78    void fini_fn(void) { if (INITIALIZER_RAN(init_fn)) ... }
79    In code, in the same file:
80    err = CALL_INIT_FUNCTION(init_fn);
81
82    To trigger or verify the initializer invocation from another file,
83    a helper function must be created.
84
85    This model handles both the load-time execution (Windows) and
86    delayed execution (pthread_once) approaches, and should be able to
87    guarantee in both cases that the init function is run once, in one
88    thread, before other stuff in the library is done; furthermore, the
89    finalization code should only run if the initialization code did.
90    (Maybe I could've made the "if INITIALIZER_RAN" test implicit, via
91    another function hidden in macros, but this is hairy enough
92    already.)
93
94    The init_fn and fini_fn names should be chosen such that any
95    exported names staring with those names, and optionally followed by
96    additional characters, fits in with any namespace constraints on
97    the library in question.
98
99
100    There's also PROGRAM_EXITING() currently always defined as zero.
101    If there's some trivial way to find out if the fini function is
102    being called because the program that the library is linked into is
103    exiting, we can just skip all the work because the resources are
104    about to be freed up anyways.  Generally this is likely to be the
105    same as distinguishing whether the library was loaded dynamically
106    while the program was running, or loaded as part of program
107    startup.  On most platforms, I don't think we can distinguish these
108    cases easily, and it's probably not worth expending any significant
109    effort.  (Note in particular that atexit() won't do, because if the
110    library is explicitly loaded and unloaded, it would have to be able
111    to deregister the atexit callback function.  Also, the system limit
112    on atexit callbacks may be small.)
113
114
115    Implementation outline:
116
117    Windows: MAKE_FINI_FUNCTION creates a symbol with a magic name that
118    is sought at library build time, and code is added to invoke the
119    function when the library is unloaded.  MAKE_INIT_FUNCTION does
120    likewise, but the function is invoked when the library is loaded,
121    and an extra variable is declared to hold an error code and a "yes
122    the initializer ran" flag.  CALL_INIT_FUNCTION blows up if the flag
123    isn't set, otherwise returns the error code.
124
125    UNIX: MAKE_INIT_FUNCTION creates and initializes a variable with a
126    name derived from the function name, containing a k5_once_t
127    (pthread_once_t or int), an error code, and a pointer to the
128    function.  The function itself is declared static, but the
129    associated variable has external linkage.  CALL_INIT_FUNCTION
130    ensures thath the function is called exactly once (pthread_once or
131    just check the flag) and returns the stored error code (or the
132    pthread_once error).
133
134    (That's the basic idea.  With some debugging assert() calls and
135    such, it's a bit more complicated.  And we also need to handle
136    doing the pthread test at run time on systems where that works, so
137    we use the k5_once_t stuff instead.)
138
139    UNIX, with compiler support: MAKE_FINI_FUNCTION declares the
140    function as a destructor, and the run time linker support or
141    whatever will cause it to be invoked when the library is unloaded,
142    the program ends, etc.
143
144    UNIX, with linker support: MAKE_FINI_FUNCTION creates a symbol with
145    a magic name that is sought at library build time, and linker
146    options are used to mark it as a finalization function for the
147    library.  The symbol must be exported.
148
149    UNIX, no library finalization support: The finalization function
150    never runs, and we leak memory.  Tough.
151
152    DELAY_INITIALIZER will be defined by the configure script if we
153    want to use k5_once instead of load-time initialization.  That'll
154    be the preferred method on most systems except Windows, where we
155    have to initialize some mutexes.
156
157
158
159
160    For maximum flexibility in defining the macros, the function name
161    parameter should be a simple name, not even a macro defined as
162    another name.  The function should have a unique name, and should
163    conform to whatever namespace is used by the library in question.
164    (We do have export lists, but (1) they're not used for all
165    platforms, and (2) they're not used for static libraries.)
166
167    If the macro expansion needs the function to have been declared, it
168    must include a declaration.  If it is not necessary for the symbol
169    name to be exported from the object file, the macro should declare
170    it as "static".  Hence the signature must exactly match "void
171    foo(void)".  (ANSI C allows a static declaration followed by a
172    non-static one; the result is internal linkage.)  The macro
173    expansion has to come before the function, because gcc apparently
174    won't act on "__attribute__((constructor))" if it comes after the
175    function definition.
176
177    This is going to be compiler- and environment-specific, and may
178    require some support at library build time, and/or "asm"
179    statements.  But through macro expansion and auxiliary functions,
180    we should be able to handle most things except #pragma.
181
182    It's okay for this code to require that the library be built
183    with the same compiler and compiler options throughout, but
184    we shouldn't require that the library and application use the
185    same compiler.
186
187    For static libraries, we don't really care about cleanup too much,
188    since it's all memory handling and mutex allocation which will all
189    be cleaned up when the program exits.  Thus, it's okay if gcc-built
190    static libraries don't play nicely with cc-built executables when
191    it comes to static constructors, just as long as it doesn't cause
192    linking to fail.
193
194    For dynamic libraries on UNIX, we'll use pthread_once-type support
195    to do delayed initialization, so if finalization can't be made to
196    work, we'll only have memory leaks in a load/use/unload cycle.  If
197    anyone (like, say, the OS vendor) complains about this, they can
198    tell us how to get a shared library finalization function invoked
199    automatically.
200
201    Currently there's --disable-delayed-initialization for preventing
202    the initialization from being delayed on UNIX, but that's mainly
203    just for testing the linker options for initialization, and will
204    probably be removed at some point.  */
205
206 /* Helper macros.  */
207
208 # define JOIN__2_2(A,B) A ## _ ## _ ## B
209 # define JOIN__2(A,B) JOIN__2_2(A,B)
210
211 /* XXX Should test USE_LINKER_INIT_OPTION early, and if it's set,
212    always provide a function by the expected name, even if we're
213    delaying initialization.  */
214
215 #if defined(DELAY_INITIALIZER)
216
217 /* Run the initialization code during program execution, at the latest
218    possible moment.  This means multiple threads may be active.  */
219 # include "k5-thread.h"
220 typedef struct { k5_once_t once; int error, did_run; void (*fn)(void); } k5_init_t;
221 # ifdef USE_LINKER_INIT_OPTION
222 #  define MAYBE_DUMMY_INIT(NAME)                \
223         void JOIN__2(NAME, auxinit) () { }
224 # else
225 #  define MAYBE_DUMMY_INIT(NAME)
226 # endif
227 # ifdef __GNUC__
228 /* Do it in macro form so we get the file/line of the invocation if
229    the assertion fails.  */
230 #  define k5_call_init_function(I)                                      \
231         (__extension__ ({                                               \
232                 k5_init_t *k5int_i = (I);                               \
233                 int k5int_err = k5_once(&k5int_i->once, k5int_i->fn);   \
234                 (k5int_err                                              \
235                  ? k5int_err                                            \
236                  : (assert(k5int_i->did_run != 0), k5int_i->error));    \
237             }))
238 #  define MAYBE_DEFINE_CALLINIT_FUNCTION
239 # else
240 #  define MAYBE_DEFINE_CALLINIT_FUNCTION                        \
241         static inline int k5_call_init_function(k5_init_t *i)   \
242         {                                                       \
243             int err;                                            \
244             err = k5_once(&i->once, i->fn);                     \
245             if (err)                                            \
246                 return err;                                     \
247             assert (i->did_run != 0);                           \
248             return i->error;                                    \
249         }
250 # endif
251 # define MAKE_INIT_FUNCTION(NAME)                               \
252         static int NAME(void);                                  \
253         MAYBE_DUMMY_INIT(NAME)                                  \
254         /* forward declaration for use in initializer */        \
255         static void JOIN__2(NAME, aux) (void);                  \
256         static k5_init_t JOIN__2(NAME, once) =                  \
257                 { K5_ONCE_INIT, 0, 0, JOIN__2(NAME, aux) };     \
258         MAYBE_DEFINE_CALLINIT_FUNCTION                          \
259         static void JOIN__2(NAME, aux) (void)                   \
260         {                                                       \
261             JOIN__2(NAME, once).did_run = 1;                    \
262             JOIN__2(NAME, once).error = NAME();                 \
263         }                                                       \
264         /* so ';' following macro use won't get error */        \
265         static int NAME(void)
266 # define CALL_INIT_FUNCTION(NAME)       \
267         k5_call_init_function(& JOIN__2(NAME, once))
268 /* This should be called in finalization only, so we shouldn't have
269    multiple active threads mucking around in our library at this
270    point.  So ignore the once_t object and just look at the flag.
271
272    XXX Could we have problems with memory coherence between processors
273    if we don't invoke mutex/once routines?  Probably not, the
274    application code should already be coordinating things such that
275    the library code is not in use by this point, and memory
276    synchronization will be needed there.  */
277 # define INITIALIZER_RAN(NAME)  \
278         (JOIN__2(NAME, once).did_run && JOIN__2(NAME, once).error == 0)
279
280 # define PROGRAM_EXITING()              (0)
281
282 #elif defined(__GNUC__) && !defined(_WIN32) && defined(CONSTRUCTOR_ATTR_WORKS)
283
284 /* Run initializer at load time, via GCC/C++ hook magic.  */
285
286 # ifdef USE_LINKER_INIT_OPTION
287      /* Both gcc and linker option??  Favor gcc.  */
288 #  define MAYBE_DUMMY_INIT(NAME)                \
289         void JOIN__2(NAME, auxinit) () { }
290 # else
291 #  define MAYBE_DUMMY_INIT(NAME)
292 # endif
293
294 typedef struct { int error; unsigned char did_run; } k5_init_t;
295 # define MAKE_INIT_FUNCTION(NAME)               \
296         MAYBE_DUMMY_INIT(NAME)                  \
297         static k5_init_t JOIN__2(NAME, ran)     \
298                 = { 0, 2 };                     \
299         static void JOIN__2(NAME, aux)(void)    \
300             __attribute__((constructor));       \
301         static int NAME(void);                  \
302         static void JOIN__2(NAME, aux)(void)    \
303         {                                       \
304             JOIN__2(NAME, ran).error = NAME();  \
305             JOIN__2(NAME, ran).did_run = 3;     \
306         }                                       \
307         static int NAME(void)
308 # define CALL_INIT_FUNCTION(NAME)               \
309         (JOIN__2(NAME, ran).did_run == 3        \
310          ? JOIN__2(NAME, ran).error             \
311          : (abort(),0))
312 # define INITIALIZER_RAN(NAME)  (JOIN__2(NAME,ran).did_run == 3 && JOIN__2(NAME, ran).error == 0)
313
314 # define PROGRAM_EXITING()              (0)
315
316 #elif defined(USE_LINKER_INIT_OPTION) || defined(_WIN32)
317
318 /* Run initializer at load time, via linker magic, or in the
319    case of WIN32, win_glue.c hard-coded knowledge.  */
320 typedef struct { int error; unsigned char did_run; } k5_init_t;
321 # define MAKE_INIT_FUNCTION(NAME)               \
322         static k5_init_t JOIN__2(NAME, ran)     \
323                 = { 0, 2 };                     \
324         static int NAME(void);                  \
325         void JOIN__2(NAME, auxinit)()           \
326         {                                       \
327             JOIN__2(NAME, ran).error = NAME();  \
328             JOIN__2(NAME, ran).did_run = 3;     \
329         }                                       \
330         static int NAME(void)
331 # define CALL_INIT_FUNCTION(NAME)               \
332         (JOIN__2(NAME, ran).did_run == 3        \
333          ? JOIN__2(NAME, ran).error             \
334          : (abort(),0))
335 # define INITIALIZER_RAN(NAME)  \
336         (JOIN__2(NAME, ran).error == 0)
337
338 # define PROGRAM_EXITING()              (0)
339
340 #else
341
342 # error "Don't know how to do load-time initializers for this configuration."
343
344 # define PROGRAM_EXITING()              (0)
345
346 #endif
347
348
349
350 #if defined(USE_LINKER_FINI_OPTION) || defined(_WIN32)
351 /* If we're told the linker option will be used, it doesn't really
352    matter what compiler we're using.  Do it the same way
353    regardless.  */
354
355 # ifdef __hpux
356
357      /* On HP-UX, we need this auxiliary function.  At dynamic load or
358         unload time (but *not* program startup and termination for
359         link-time specified libraries), the linker-indicated function
360         is called with a handle on the library and a flag indicating
361         whether it's being loaded or unloaded.
362
363         The "real" fini function doesn't need to be exported, so
364         declare it static.
365
366         As usual, the final declaration is just for syntactic
367         convenience, so the top-level invocation of this macro can be
368         followed by a semicolon.  */
369
370 #  include <dl.h>
371 #  define MAKE_FINI_FUNCTION(NAME)                                          \
372         static void NAME(void);                                             \
373         void JOIN__2(NAME, auxfini)(shl_t, int); /* silence gcc warnings */ \
374         void JOIN__2(NAME, auxfini)(shl_t h, int l) { if (!l) NAME(); }     \
375         static void NAME(void)
376
377 # else /* not hpux */
378
379 #  define MAKE_FINI_FUNCTION(NAME)      \
380         void NAME(void)
381
382 # endif
383
384 #elif defined(__GNUC__) && defined(DESTRUCTOR_ATTR_WORKS)
385 /* If we're using gcc, if the C++ support works, the compiler should
386    build executables and shared libraries that support the use of
387    static constructors and destructors.  The C compiler supports a
388    function attribute that makes use of the same facility as C++.
389
390    XXX How do we know if the C++ support actually works?  */
391 # define MAKE_FINI_FUNCTION(NAME)       \
392         static void NAME(void) __attribute__((destructor))
393
394 #elif !defined(SHARED)
395
396 /* In this case, we just don't care about finalization.
397
398    The code will still define the function, but we won't do anything
399    with it.  Annoying: This may generate unused-function warnings.  */
400
401 # define MAKE_FINI_FUNCTION(NAME)       \
402         static void NAME(void)
403
404 #else
405
406 # error "Don't know how to do unload-time finalization for this configuration."
407
408 #endif
409
410
411 /* 64-bit support: krb5_ui_8 and krb5_int64.
412
413    This should move to krb5.h eventually, but without the namespace
414    pollution from the autoconf macros.  */
415 #if defined(HAVE_STDINT_H) || defined(HAVE_INTTYPES_H)
416 # ifdef HAVE_STDINT_H
417 #  include <stdint.h>
418 # endif
419 # ifdef HAVE_INTTYPES_H
420 #  include <inttypes.h>
421 # endif
422 # define INT64_TYPE int64_t
423 # define UINT64_TYPE uint64_t
424 #elif defined(_WIN32)
425 # define INT64_TYPE signed __int64
426 # define UINT64_TYPE unsigned __int64
427 #else /* not Windows, and neither stdint.h nor inttypes.h */
428 # define INT64_TYPE signed long long
429 # define UINT64_TYPE unsigned long long
430 #endif
431
432 #ifndef SIZE_MAX
433 # define SIZE_MAX ((size_t)((size_t)0 - 1))
434 #endif
435
436 #ifndef UINT64_MAX
437 # define UINT64_MAX ((UINT64_TYPE)((UINT64_TYPE)0 - 1))
438 #endif
439
440 #ifdef _WIN32
441 # define SSIZE_MAX ((ssize_t)(SIZE_MAX/2))
442 #endif
443
444 /* Read and write integer values as (unaligned) octet strings in
445    specific byte orders.  Add per-platform optimizations as
446    needed.  */
447
448 #if HAVE_ENDIAN_H
449 # include <endian.h>
450 #elif HAVE_MACHINE_ENDIAN_H
451 # include <machine/endian.h>
452 #endif
453 /* Check for BIG/LITTLE_ENDIAN macros.  If exactly one is defined, use
454    it.  If both are defined, then BYTE_ORDER should be defined and
455    match one of them.  Try those symbols, then try again with an
456    underscore prefix.  */
457 #if defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN)
458 # if BYTE_ORDER == BIG_ENDIAN
459 #  define K5_BE
460 # endif
461 # if BYTE_ORDER == LITTLE_ENDIAN
462 #  define K5_LE
463 # endif
464 #elif defined(BIG_ENDIAN)
465 # define K5_BE
466 #elif defined(LITTLE_ENDIAN)
467 # define K5_LE
468 #elif defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
469 # if _BYTE_ORDER == _BIG_ENDIAN
470 #  define K5_BE
471 # endif
472 # if _BYTE_ORDER == _LITTLE_ENDIAN
473 #  define K5_LE
474 # endif
475 #elif defined(_BIG_ENDIAN)
476 # define K5_BE
477 #elif defined(_LITTLE_ENDIAN)
478 # define K5_LE
479 #elif defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
480 # define K5_BE
481 #elif defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
482 # define K5_LE
483 #endif
484 #if !defined(K5_BE) && !defined(K5_LE)
485 /* Look for some architectures we know about.
486
487    MIPS can use either byte order, but the preprocessor tells us which
488    mode we're compiling for.  The GCC config files indicate that
489    variants of Alpha and IA64 might be out there with both byte
490    orders, but until we encounter the "wrong" ones in the real world,
491    just go with the default (unless there are cpp predefines to help
492    us there too).
493
494    As far as I know, only PDP11 and ARM (which we don't handle here)
495    have strange byte orders where an 8-byte value isn't laid out as
496    either 12345678 or 87654321.  */
497 # if defined(__i386__) || defined(_MIPSEL) || defined(__alpha__) || (defined(__ia64__) && !defined(__hpux))
498 #  define K5_LE
499 # endif
500 # if defined(__hppa__) || defined(__rs6000__) || defined(__sparc__) || defined(_MIPSEB) || defined(__m68k__) || defined(__sparc64__) || defined(__ppc__) || defined(__ppc64__) || (defined(__hpux) && defined(__ia64__))
501 #  define K5_BE
502 # endif
503 #endif
504 #if defined(K5_BE) && defined(K5_LE)
505 # error "oops, check the byte order macros"
506 #endif
507
508 /* Optimize for GCC on platforms with known byte orders.
509
510    GCC's packed structures can be written to with any alignment; the
511    compiler will use byte operations, unaligned-word operations, or
512    normal memory ops as appropriate for the architecture.
513
514    This assumes the availability of uint##_t types, which should work
515    on most of our platforms except Windows, where we're not using
516    GCC.  */
517 #ifdef __GNUC__
518 # define PUT(SIZE,PTR,VAL)      (((struct { uint##SIZE##_t i; } __attribute__((packed)) *)(PTR))->i = (VAL))
519 # define GET(SIZE,PTR)          (((const struct { uint##SIZE##_t i; } __attribute__((packed)) *)(PTR))->i)
520 # define PUTSWAPPED(SIZE,PTR,VAL)       PUT(SIZE,PTR,SWAP##SIZE(VAL))
521 # define GETSWAPPED(SIZE,PTR)           SWAP##SIZE(GET(SIZE,PTR))
522 #endif
523 /* To do: Define SWAP16, SWAP32, SWAP64 macros to byte-swap values
524    with the indicated numbers of bits.
525
526    Linux: byteswap.h, bswap_16 etc.
527    Solaris 10: none
528    Mac OS X: machine/endian.h or byte_order.h, NXSwap{Short,Int,LongLong}
529    NetBSD: sys/bswap.h, bswap16 etc.  */
530
531 #if defined(HAVE_BYTESWAP_H) && defined(HAVE_BSWAP_16)
532 # include <byteswap.h>
533 # define SWAP16                 bswap_16
534 # define SWAP32                 bswap_32
535 # ifdef HAVE_BSWAP_64
536 #  define SWAP64                bswap_64
537 # endif
538 #elif TARGET_OS_MAC
539 # include <architecture/byte_order.h>
540 # if 0 /* This causes compiler warnings.  */
541 #  define SWAP16                OSSwapInt16
542 # else
543 #  define SWAP16                k5_swap16
544 static inline unsigned int k5_swap16 (unsigned int x) {
545     x &= 0xffff;
546     return (x >> 8) | ((x & 0xff) << 8);
547 }
548 # endif
549 # define SWAP32                 OSSwapInt32
550 # define SWAP64                 OSSwapInt64
551 #elif defined(HAVE_SYS_BSWAP_H)
552 /* XXX NetBSD/x86 5.0.1 defines bswap16 and bswap32 as inline
553    functions only, so autoconf doesn't pick up on their existence.
554    So, no feature macro test for them here.  The 64-bit version isn't
555    inline at all, though, for whatever reason.  */
556 # include <sys/bswap.h>
557 # define SWAP16                 bswap16
558 # define SWAP32                 bswap32
559 /* However, bswap64 causes lots of warnings about 'long long'
560    constants; probably only on 32-bit platforms.  */
561 # if LONG_MAX > 0x7fffffffL
562 #  define SWAP64                bswap64
563 # endif
564 #endif
565
566 /* Note that on Windows at least this file can be included from C++
567    source, so casts *from* void* are required.  */
568 static inline void
569 store_16_be (unsigned int val, void *vp)
570 {
571     unsigned char *p = (unsigned char *) vp;
572 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus)
573     PUT(16,p,val);
574 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP16) && !defined(__cplusplus)
575     PUTSWAPPED(16,p,val);
576 #else
577     p[0] = (val >>  8) & 0xff;
578     p[1] = (val      ) & 0xff;
579 #endif
580 }
581 static inline void
582 store_32_be (unsigned int val, void *vp)
583 {
584     unsigned char *p = (unsigned char *) vp;
585 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus)
586     PUT(32,p,val);
587 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP32) && !defined(__cplusplus)
588     PUTSWAPPED(32,p,val);
589 #else
590     p[0] = (val >> 24) & 0xff;
591     p[1] = (val >> 16) & 0xff;
592     p[2] = (val >>  8) & 0xff;
593     p[3] = (val      ) & 0xff;
594 #endif
595 }
596 static inline void
597 store_64_be (UINT64_TYPE val, void *vp)
598 {
599     unsigned char *p = (unsigned char *) vp;
600 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus)
601     PUT(64,p,val);
602 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP64) && !defined(__cplusplus)
603     PUTSWAPPED(64,p,val);
604 #else
605     p[0] = (unsigned char)((val >> 56) & 0xff);
606     p[1] = (unsigned char)((val >> 48) & 0xff);
607     p[2] = (unsigned char)((val >> 40) & 0xff);
608     p[3] = (unsigned char)((val >> 32) & 0xff);
609     p[4] = (unsigned char)((val >> 24) & 0xff);
610     p[5] = (unsigned char)((val >> 16) & 0xff);
611     p[6] = (unsigned char)((val >>  8) & 0xff);
612     p[7] = (unsigned char)((val      ) & 0xff);
613 #endif
614 }
615 static inline unsigned short
616 load_16_be (const void *cvp)
617 {
618     const unsigned char *p = (const unsigned char *) cvp;
619 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus)
620     return GET(16,p);
621 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP16) && !defined(__cplusplus)
622     return GETSWAPPED(16,p);
623 #else
624     return (p[1] | (p[0] << 8));
625 #endif
626 }
627 static inline unsigned int
628 load_32_be (const void *cvp)
629 {
630     const unsigned char *p = (const unsigned char *) cvp;
631 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus)
632     return GET(32,p);
633 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP32) && !defined(__cplusplus)
634     return GETSWAPPED(32,p);
635 #else
636     return (p[3] | (p[2] << 8)
637             | ((uint32_t) p[1] << 16)
638             | ((uint32_t) p[0] << 24));
639 #endif
640 }
641 static inline UINT64_TYPE
642 load_64_be (const void *cvp)
643 {
644     const unsigned char *p = (const unsigned char *) cvp;
645 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus)
646     return GET(64,p);
647 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP64) && !defined(__cplusplus)
648     return GETSWAPPED(64,p);
649 #else
650     return ((UINT64_TYPE)load_32_be(p) << 32) | load_32_be(p+4);
651 #endif
652 }
653 static inline void
654 store_16_le (unsigned int val, void *vp)
655 {
656     unsigned char *p = (unsigned char *) vp;
657 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus)
658     PUT(16,p,val);
659 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP16) && !defined(__cplusplus)
660     PUTSWAPPED(16,p,val);
661 #else
662     p[1] = (val >>  8) & 0xff;
663     p[0] = (val      ) & 0xff;
664 #endif
665 }
666 static inline void
667 store_32_le (unsigned int val, void *vp)
668 {
669     unsigned char *p = (unsigned char *) vp;
670 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus)
671     PUT(32,p,val);
672 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP32) && !defined(__cplusplus)
673     PUTSWAPPED(32,p,val);
674 #else
675     p[3] = (val >> 24) & 0xff;
676     p[2] = (val >> 16) & 0xff;
677     p[1] = (val >>  8) & 0xff;
678     p[0] = (val      ) & 0xff;
679 #endif
680 }
681 static inline void
682 store_64_le (UINT64_TYPE val, void *vp)
683 {
684     unsigned char *p = (unsigned char *) vp;
685 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus)
686     PUT(64,p,val);
687 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP64) && !defined(__cplusplus)
688     PUTSWAPPED(64,p,val);
689 #else
690     p[7] = (unsigned char)((val >> 56) & 0xff);
691     p[6] = (unsigned char)((val >> 48) & 0xff);
692     p[5] = (unsigned char)((val >> 40) & 0xff);
693     p[4] = (unsigned char)((val >> 32) & 0xff);
694     p[3] = (unsigned char)((val >> 24) & 0xff);
695     p[2] = (unsigned char)((val >> 16) & 0xff);
696     p[1] = (unsigned char)((val >>  8) & 0xff);
697     p[0] = (unsigned char)((val      ) & 0xff);
698 #endif
699 }
700 static inline unsigned short
701 load_16_le (const void *cvp)
702 {
703     const unsigned char *p = (const unsigned char *) cvp;
704 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus)
705     return GET(16,p);
706 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP16) && !defined(__cplusplus)
707     return GETSWAPPED(16,p);
708 #else
709     return (p[0] | (p[1] << 8));
710 #endif
711 }
712 static inline unsigned int
713 load_32_le (const void *cvp)
714 {
715     const unsigned char *p = (const unsigned char *) cvp;
716 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus)
717     return GET(32,p);
718 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP32) && !defined(__cplusplus)
719     return GETSWAPPED(32,p);
720 #else
721     return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24));
722 #endif
723 }
724 static inline UINT64_TYPE
725 load_64_le (const void *cvp)
726 {
727     const unsigned char *p = (const unsigned char *) cvp;
728 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus)
729     return GET(64,p);
730 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP64) && !defined(__cplusplus)
731     return GETSWAPPED(64,p);
732 #else
733     return ((UINT64_TYPE)load_32_le(p+4) << 32) | load_32_le(p);
734 #endif
735 }
736
737 #ifdef _WIN32
738 #define UINT16_TYPE unsigned __int16
739 #define UINT32_TYPE unsigned __int32
740 #else
741 #define UINT16_TYPE uint16_t
742 #define UINT32_TYPE uint32_t
743 #endif
744
745 static inline void
746 store_16_n (unsigned int val, void *vp)
747 {
748     UINT16_TYPE n = val;
749     memcpy(vp, &n, 2);
750 }
751 static inline void
752 store_32_n (unsigned int val, void *vp)
753 {
754     UINT32_TYPE n = val;
755     memcpy(vp, &n, 4);
756 }
757 static inline void
758 store_64_n (UINT64_TYPE val, void *vp)
759 {
760     UINT64_TYPE n = val;
761     memcpy(vp, &n, 8);
762 }
763 static inline unsigned short
764 load_16_n (const void *p)
765 {
766     UINT16_TYPE n;
767     memcpy(&n, p, 2);
768     return n;
769 }
770 static inline unsigned int
771 load_32_n (const void *p)
772 {
773     UINT32_TYPE n;
774     memcpy(&n, p, 4);
775     return n;
776 }
777 static inline UINT64_TYPE
778 load_64_n (const void *p)
779 {
780     UINT64_TYPE n;
781     memcpy(&n, p, 8);
782     return n;
783 }
784 #undef UINT16_TYPE
785 #undef UINT32_TYPE
786
787 /* Assume for simplicity that these swaps are identical.  */
788 static inline UINT64_TYPE
789 k5_htonll (UINT64_TYPE val)
790 {
791 #ifdef K5_BE
792     return val;
793 #elif defined K5_LE && defined SWAP64
794     return SWAP64 (val);
795 #else
796     return load_64_be ((unsigned char *)&val);
797 #endif
798 }
799 static inline UINT64_TYPE
800 k5_ntohll (UINT64_TYPE val)
801 {
802     return k5_htonll (val);
803 }
804
805 /* Make the interfaces to getpwnam and getpwuid consistent.
806    Model the wrappers on the POSIX thread-safe versions, but
807    use the unsafe system versions if the safe ones don't exist
808    or we can't figure out their interfaces.  */
809
810 /* int k5_getpwnam_r(const char *, blah blah) */
811 #ifdef HAVE_GETPWNAM_R
812 # ifndef GETPWNAM_R_4_ARGS
813 /* POSIX */
814 #  define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT)   \
815         (getpwnam_r(NAME,REC,BUF,BUFSIZE,OUT) == 0      \
816          ? (*(OUT) == NULL ? -1 : 0) : -1)
817 # else
818 /* POSIX drafts? */
819 #  ifdef GETPWNAM_R_RETURNS_INT
820 #   define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT)  \
821         (getpwnam_r(NAME,REC,BUF,BUFSIZE) == 0          \
822          ? (*(OUT) = REC, 0)                            \
823          : (*(OUT) = NULL, -1))
824 #  else
825 #   define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT)  \
826         (*(OUT) = getpwnam_r(NAME,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0)
827 #  endif
828 # endif
829 #else /* no getpwnam_r, or can't figure out #args or return type */
830 /* Will get warnings about unused variables.  */
831 # define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT) \
832         (*(OUT) = getpwnam(NAME), *(OUT) == NULL ? -1 : 0)
833 #endif
834
835 /* int k5_getpwuid_r(uid_t, blah blah) */
836 #ifdef HAVE_GETPWUID_R
837 # ifndef GETPWUID_R_4_ARGS
838 /* POSIX */
839 #  define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT)    \
840         (getpwuid_r(UID,REC,BUF,BUFSIZE,OUT) == 0       \
841          ? (*(OUT) == NULL ? -1 : 0) : -1)
842 # else
843 /* POSIX drafts?  Yes, I mean to test GETPWNAM... here.  Less junk to
844    do at configure time.  */
845 #  ifdef GETPWNAM_R_RETURNS_INT
846 #   define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT)   \
847         (getpwuid_r(UID,REC,BUF,BUFSIZE) == 0           \
848          ? (*(OUT) = REC, 0)                            \
849          : (*(OUT) = NULL, -1))
850 #  else
851 #   define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT)  \
852         (*(OUT) = getpwuid_r(UID,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0)
853 #  endif
854 # endif
855 #else /* no getpwuid_r, or can't figure out #args or return type */
856 /* Will get warnings about unused variables.  */
857 # define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \
858         (*(OUT) = getpwuid(UID), *(OUT) == NULL ? -1 : 0)
859 #endif
860
861 /* Ensure, if possible, that the indicated file descriptor won't be
862    kept open if we exec another process (e.g., launching a ccapi
863    server).  If we don't know how to do it... well, just go about our
864    business.  Probably most callers won't check the return status
865    anyways.  */
866
867 #if 0
868 static inline int
869 set_cloexec_fd(int fd)
870 {
871 #if defined(F_SETFD)
872 # ifdef FD_CLOEXEC
873     if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0)
874         return errno;
875 # else
876     if (fcntl(fd, F_SETFD, 1) != 0)
877         return errno;
878 # endif
879 #endif
880     return 0;
881 }
882
883 static inline int
884 set_cloexec_file(FILE *f)
885 {
886     return set_cloexec_fd(fileno(f));
887 }
888 #else
889 /* Macros make the Sun compiler happier, and all variants of this do a
890    single evaluation of the argument, and fcntl and fileno should
891    produce reasonable error messages on type mismatches, on any system
892    with F_SETFD.  */
893 #ifdef F_SETFD
894 # ifdef FD_CLOEXEC
895 #  define set_cloexec_fd(FD)    (fcntl((FD), F_SETFD, FD_CLOEXEC) ? errno : 0)
896 # else
897 #  define set_cloexec_fd(FD)    (fcntl((FD), F_SETFD, 1) ? errno : 0)
898 # endif
899 #else
900 # define set_cloexec_fd(FD)     ((FD),0)
901 #endif
902 #define set_cloexec_file(F)     set_cloexec_fd(fileno(F))
903 #endif
904
905
906
907 /* Since the original ANSI C spec left it undefined whether or
908    how you could copy around a va_list, C 99 added va_copy.
909    For old implementations, let's do our best to fake it.
910
911    XXX Doesn't yet handle implementations with __va_copy (early draft)
912    or GCC's __builtin_va_copy.  */
913 #if defined(HAS_VA_COPY) || defined(va_copy)
914 /* Do nothing.  */
915 #elif defined(CAN_COPY_VA_LIST)
916 #define va_copy(dest, src)      ((dest) = (src))
917 #else
918 /* Assume array type, but still simply copyable.
919
920    There is, theoretically, the possibility that va_start will
921    allocate some storage pointed to by the va_list, and in that case
922    we'll just lose.  If anyone cares, we could try to devise a test
923    for that case.  */
924 #define va_copy(dest, src)      memcpy(dest, src, sizeof(va_list))
925 #endif
926
927 /* Provide strlcpy/strlcat interfaces. */
928 #ifndef HAVE_STRLCPY
929 #define strlcpy krb5int_strlcpy
930 #define strlcat krb5int_strlcat
931 extern size_t krb5int_strlcpy(char *dst, const char *src, size_t siz);
932 extern size_t krb5int_strlcat(char *dst, const char *src, size_t siz);
933 #endif
934
935 /* Provide fnmatch interface. */
936 #ifndef HAVE_FNMATCH
937 #define fnmatch k5_fnmatch
938 int k5_fnmatch(const char *pattern, const char *string, int flags);
939 #define FNM_NOMATCH     1       /* Match failed. */
940 #define FNM_NOSYS       2       /* Function not implemented. */
941 #define FNM_NORES       3       /* Out of resources */
942 #define FNM_NOESCAPE    0x01    /* Disable backslash escaping. */
943 #define FNM_PATHNAME    0x02    /* Slash must be matched by slash. */
944 #define FNM_PERIOD      0x04    /* Period must be matched by period. */
945 #define FNM_CASEFOLD    0x08    /* Pattern is matched case-insensitive */
946 #define FNM_LEADING_DIR 0x10    /* Ignore /<tail> after Imatch. */
947 #endif
948
949 /* Provide [v]asprintf interfaces.  */
950 #ifndef HAVE_VSNPRINTF
951 #ifdef _WIN32
952 static inline int
953 vsnprintf(char *str, size_t size, const char *format, va_list args)
954 {
955     va_list args_copy;
956     int length;
957
958     va_copy(args_copy, args);
959     length = _vscprintf(format, args_copy);
960     va_end(args_copy);
961     if (size > 0) {
962         _vsnprintf(str, size, format, args);
963         str[size - 1] = '\0';
964     }
965     return length;
966 }
967 static inline int
968 snprintf(char *str, size_t size, const char *format, ...)
969 {
970     va_list args;
971     int n;
972
973     va_start(args, format);
974     n = vsnprintf(str, size, format, args);
975     va_end(args);
976     return n;
977 }
978 #else /* not win32 */
979 #error We need an implementation of vsnprintf.
980 #endif /* win32? */
981 #endif /* no vsnprintf */
982
983 #ifndef HAVE_VASPRINTF
984
985 extern int krb5int_vasprintf(char **, const char *, va_list)
986 #if !defined(__cplusplus) && (__GNUC__ > 2)
987     __attribute__((__format__(__printf__, 2, 0)))
988 #endif
989     ;
990 extern int krb5int_asprintf(char **, const char *, ...)
991 #if !defined(__cplusplus) && (__GNUC__ > 2)
992     __attribute__((__format__(__printf__, 2, 3)))
993 #endif
994     ;
995
996 #define vasprintf krb5int_vasprintf
997 /* Assume HAVE_ASPRINTF iff HAVE_VASPRINTF.  */
998 #define asprintf krb5int_asprintf
999
1000 #elif defined(NEED_VASPRINTF_PROTO)
1001
1002 extern int vasprintf(char **, const char *, va_list)
1003 #if !defined(__cplusplus) && (__GNUC__ > 2)
1004     __attribute__((__format__(__printf__, 2, 0)))
1005 #endif
1006     ;
1007 extern int asprintf(char **, const char *, ...)
1008 #if !defined(__cplusplus) && (__GNUC__ > 2)
1009     __attribute__((__format__(__printf__, 2, 3)))
1010 #endif
1011     ;
1012
1013 #endif /* have vasprintf and prototype? */
1014
1015 /* Return true if the snprintf return value RESULT reflects a buffer
1016    overflow for the buffer size SIZE.
1017
1018    We cast the result to unsigned int for two reasons.  First, old
1019    implementations of snprintf (such as the one in Solaris 9 and
1020    prior) return -1 on a buffer overflow.  Casting the result to -1
1021    will convert that value to UINT_MAX, which should compare larger
1022    than any reasonable buffer size.  Second, comparing signed and
1023    unsigned integers will generate warnings with some compilers, and
1024    can have unpredictable results, particularly when the relative
1025    widths of the types is not known (size_t may be the same width as
1026    int or larger).
1027 */
1028 #define SNPRINTF_OVERFLOW(result, size) \
1029     ((unsigned int)(result) >= (size_t)(size))
1030
1031 #ifndef HAVE_MKSTEMP
1032 extern int krb5int_mkstemp(char *);
1033 #define mkstemp krb5int_mkstemp
1034 #endif
1035
1036 #ifndef HAVE_GETTIMEOFDAY
1037 extern int krb5int_gettimeofday(struct timeval *tp, void *ignore);
1038 #define gettimeofday krb5int_gettimeofday
1039 #endif
1040
1041 extern void krb5int_zap(void *ptr, size_t len);
1042
1043 /*
1044  * Split a path into parent directory and basename.  Either output parameter
1045  * may be NULL if the caller doesn't need it.  parent_out will be empty if path
1046  * has no basename.  basename_out will be empty if path ends with a path
1047  * separator.  Returns 0 on success or ENOMEM on allocation failure.
1048  */
1049 long k5_path_split(const char *path, char **parent_out, char **basename_out);
1050
1051 /*
1052  * Compose two path components, inserting the platform-appropriate path
1053  * separator if needed.  If path2 is an absolute path, path1 will be discarded
1054  * and path_out will be a copy of path2.  Returns 0 on success or ENOMEM on
1055  * allocation failure.
1056  */
1057 long k5_path_join(const char *path1, const char *path2, char **path_out);
1058
1059 /* Return 1 if path is absolute, 0 if it is relative. */
1060 int k5_path_isabs(const char *path);
1061
1062 /*
1063  * Localization macros.  If we have gettext, define _ appropriately for
1064  * translating a string.  If we do not have gettext, define _, bindtextdomain,
1065  * and setlocale as no-ops.  N_ is always a no-op; it marks a string for
1066  * extraction to pot files but does not translate it.
1067  */
1068 #ifdef ENABLE_NLS
1069 #include <libintl.h>
1070 #include <locale.h>
1071 #define KRB5_TEXTDOMAIN "mit-krb5"
1072 #define _(s) dgettext(KRB5_TEXTDOMAIN, s)
1073 #else
1074 #define _(s) s
1075 #define dgettext(d, m) m
1076 #define bindtextdomain(p, d)
1077 #define setlocale(c, l)
1078 #endif
1079 #define N_(s) s
1080
1081 #endif /* K5_PLATFORM_H */