2 * Copyright (c) 2010 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 #include <sys/types.h>
43 #include <sys/socket.h>
45 #if !defined(WIN32) && !defined(HAVE_DISPATCH_DISPATCH_H) && defined(ENABLE_PTHREAD_SUPPORT)
48 #include <krb5-types.h>
69 #define HEIM_CALLCONV __stdcall
70 #define HEIM_LIB_CALL __stdcall
76 #if !defined(__GNUC__) && !defined(__attribute__)
77 #define __attribute__(x)
80 #define HEIM_BASE_API_VERSION 20130210
83 * Generic facilities (moved from lib/krb5/.
86 typedef int32_t heim_error_code
;
87 typedef struct heim_context_s
*heim_context
;
88 typedef struct heim_pcontext_s
*heim_pcontext
;
90 typedef void (HEIM_CALLCONV
*heim_log_log_func_t
)(heim_context
,
94 typedef void (HEIM_CALLCONV
*heim_log_close_func_t
)(void *);
96 struct heim_log_facility_internal
{
99 heim_log_log_func_t log_func
;
100 heim_log_close_func_t close_func
;
104 typedef struct heim_log_facility_s
{
107 struct heim_log_facility_internal
*val
;
111 (HEIM_LIB_CALL
*heim_get_instance_func_t
)(const char *);
113 #define HEIM_PLUGIN_INVOKE_ALL 1
115 struct heim_plugin_data
{
120 heim_get_instance_func_t get_instance
;
124 * heim_config_binding is identical to struct krb5_config_binding
125 * within krb5.h. Its format is public and used by callers of
126 * krb5_config_get_list() and krb5_config_vget_list().
128 enum heim_config_type
{
132 struct heim_config_binding
{
133 enum heim_config_type type
;
135 struct heim_config_binding
*next
;
138 struct heim_config_binding
*list
;
142 typedef struct heim_config_binding heim_config_binding
;
143 typedef struct heim_config_binding heim_config_section
;
149 typedef void * heim_object_t
;
150 typedef unsigned int heim_tid_t
;
151 typedef heim_object_t heim_bool_t
;
152 typedef heim_object_t heim_null_t
;
154 typedef LONG heim_base_once_t
;
155 #define HEIM_BASE_ONCE_INIT 0
156 #elif defined(HAVE_DISPATCH_DISPATCH_H)
157 typedef long heim_base_once_t
; /* XXX arch dependant */
158 #define HEIM_BASE_ONCE_INIT 0
159 #elif defined(ENABLE_PTHREAD_SUPPORT)
160 typedef pthread_once_t heim_base_once_t
;
161 #define HEIM_BASE_ONCE_INIT PTHREAD_ONCE_INIT
163 typedef long heim_base_once_t
; /* XXX arch dependant */
164 #define HEIM_BASE_ONCE_INIT 0
167 #if !defined(__has_extension)
168 #define __has_extension(x) 0
171 #define HEIM_REQUIRE_GNUC(m,n,p) \
172 (((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + __GNUC_PATCHLEVEL__) >= \
173 (((m) * 10000) + ((n) * 100) + (p)))
176 #if __has_extension(__builtin_expect) || HEIM_REQUIRE_GNUC(3,0,0)
177 #define heim_builtin_expect(_op,_res) __builtin_expect(_op,_res)
179 #define heim_builtin_expect(_op,_res) (_op)
183 void * heim_retain(heim_object_t
);
184 void heim_release(heim_object_t
);
186 void heim_show(heim_object_t
);
188 typedef void (*heim_type_dealloc
)(void *);
191 heim_alloc(size_t size
, const char *name
, heim_type_dealloc dealloc
);
194 heim_get_tid(heim_object_t object
);
197 heim_cmp(heim_object_t a
, heim_object_t b
);
200 heim_get_hash(heim_object_t ptr
);
203 heim_base_once_f(heim_base_once_t
*, void *, void (*)(void *));
206 heim_abort(const char *fmt
, ...)
207 HEIMDAL_NORETURN_ATTRIBUTE
208 HEIMDAL_PRINTF_ATTRIBUTE((__printf__
, 1, 2));
211 heim_abortv(const char *fmt
, va_list ap
)
212 HEIMDAL_NORETURN_ATTRIBUTE
213 HEIMDAL_PRINTF_ATTRIBUTE((__printf__
, 1, 0));
215 #define heim_assert(e,t) \
216 (heim_builtin_expect(!(e), 0) ? heim_abort(t ":" #e) : (void)0)
223 heim_null_create(void);
226 heim_bool_create(int);
229 heim_bool_val(heim_bool_t
);
235 typedef struct heim_array_data
*heim_array_t
;
237 heim_array_t
heim_array_create(void);
238 heim_tid_t
heim_array_get_type_id(void);
240 typedef void (*heim_array_iterator_f_t
)(heim_object_t
, void *, int *);
241 typedef int (*heim_array_filter_f_t
)(heim_object_t
, void *);
243 int heim_array_append_value(heim_array_t
, heim_object_t
);
244 int heim_array_insert_value(heim_array_t
, size_t idx
, heim_object_t
);
245 void heim_array_iterate_f(heim_array_t
, void *, heim_array_iterator_f_t
);
246 void heim_array_iterate_reverse_f(heim_array_t
, void *, heim_array_iterator_f_t
);
248 void heim_array_iterate(heim_array_t
, void (^)(heim_object_t
, int *));
249 void heim_array_iterate_reverse(heim_array_t
, void (^)(heim_object_t
, int *));
251 size_t heim_array_get_length(heim_array_t
);
253 heim_array_get_value(heim_array_t
, size_t);
255 heim_array_copy_value(heim_array_t
, size_t);
256 void heim_array_set_value(heim_array_t
, size_t, heim_object_t
);
257 void heim_array_delete_value(heim_array_t
, size_t);
258 void heim_array_filter_f(heim_array_t
, void *, heim_array_filter_f_t
);
260 void heim_array_filter(heim_array_t
, int (^)(heim_object_t
));
267 typedef struct heim_dict_data
*heim_dict_t
;
269 heim_dict_t
heim_dict_create(size_t size
);
270 heim_tid_t
heim_dict_get_type_id(void);
272 typedef void (*heim_dict_iterator_f_t
)(heim_object_t
, heim_object_t
, void *);
274 int heim_dict_set_value(heim_dict_t
, heim_object_t
, heim_object_t
);
275 void heim_dict_iterate_f(heim_dict_t
, void *, heim_dict_iterator_f_t
);
277 void heim_dict_iterate(heim_dict_t
, void (^)(heim_object_t
, heim_object_t
));
281 heim_dict_get_value(heim_dict_t
, heim_object_t
);
283 heim_dict_copy_value(heim_dict_t
, heim_object_t
);
284 void heim_dict_delete_key(heim_dict_t
, heim_object_t
);
290 typedef struct heim_string_data
*heim_string_t
;
291 typedef void (*heim_string_free_f_t
)(void *);
293 heim_string_t
heim_string_create(const char *);
294 heim_string_t
heim_string_ref_create(const char *, heim_string_free_f_t
);
295 heim_string_t
heim_string_create_with_bytes(const void *, size_t);
296 heim_string_t
heim_string_ref_create_with_bytes(const void *, size_t,
297 heim_string_free_f_t
);
298 heim_string_t
heim_string_create_with_format(const char *, ...);
299 heim_tid_t
heim_string_get_type_id(void);
300 const char * heim_string_get_utf8(heim_string_t
);
302 #define HSTR(_str) (__heim_string_constant("" _str ""))
303 heim_string_t
__heim_string_constant(const char *);
309 typedef struct heim_error
* heim_error_t
;
311 heim_error_t
heim_error_create_enomem(void);
313 heim_error_t
heim_error_create(int, const char *, ...)
314 HEIMDAL_PRINTF_ATTRIBUTE((__printf__
, 2, 3));
316 void heim_error_create_opt(heim_error_t
*error
, int error_code
, const char *fmt
, ...)
317 HEIMDAL_PRINTF_ATTRIBUTE((__printf__
, 3, 4));
319 heim_error_t
heim_error_createv(int, const char *, va_list)
320 HEIMDAL_PRINTF_ATTRIBUTE((__printf__
, 2, 0));
322 heim_string_t
heim_error_copy_string(heim_error_t
);
323 int heim_error_get_code(heim_error_t
);
325 heim_error_t
heim_error_append(heim_error_t
, heim_error_t
);
331 heim_object_t
heim_path_get(heim_object_t ptr
, heim_error_t
*error
, ...);
332 heim_object_t
heim_path_copy(heim_object_t ptr
, heim_error_t
*error
, ...);
333 heim_object_t
heim_path_vget(heim_object_t ptr
, heim_error_t
*error
,
335 heim_object_t
heim_path_vcopy(heim_object_t ptr
, heim_error_t
*error
,
338 int heim_path_vcreate(heim_object_t ptr
, size_t size
, heim_object_t leaf
,
339 heim_error_t
*error
, va_list ap
);
340 int heim_path_create(heim_object_t ptr
, size_t size
, heim_object_t leaf
,
341 heim_error_t
*error
, ...);
343 void heim_path_vdelete(heim_object_t ptr
, heim_error_t
*error
, va_list ap
);
344 void heim_path_delete(heim_object_t ptr
, heim_error_t
*error
, ...);
347 * Data (octet strings)
350 #ifndef __HEIM_BASE_DATA__
351 #define __HEIM_BASE_DATA__
352 struct heim_base_data
{
356 typedef struct heim_base_data heim_octet_string
;
359 typedef struct heim_base_data
* heim_data_t
;
360 typedef void (*heim_data_free_f_t
)(void *);
362 heim_data_t
heim_data_create(const void *, size_t);
363 heim_data_t
heim_data_ref_create(const void *, size_t, heim_data_free_f_t
);
364 heim_tid_t
heim_data_get_type_id(void);
365 const heim_octet_string
*
366 heim_data_get_data(heim_data_t
);
367 const void * heim_data_get_ptr(heim_data_t
);
368 size_t heim_data_get_length(heim_data_t
);
374 typedef struct heim_db_data
*heim_db_t
;
376 typedef void (*heim_db_iterator_f_t
)(heim_data_t
, heim_data_t
, void *);
378 typedef int (*heim_db_plug_open_f_t
)(void *, const char *, const char *,
379 heim_dict_t
, void **, heim_error_t
*);
380 typedef int (*heim_db_plug_clone_f_t
)(void *, void **, heim_error_t
*);
381 typedef int (*heim_db_plug_close_f_t
)(void *, heim_error_t
*);
382 typedef int (*heim_db_plug_lock_f_t
)(void *, int, heim_error_t
*);
383 typedef int (*heim_db_plug_unlock_f_t
)(void *, heim_error_t
*);
384 typedef int (*heim_db_plug_sync_f_t
)(void *, heim_error_t
*);
385 typedef int (*heim_db_plug_begin_f_t
)(void *, int, heim_error_t
*);
386 typedef int (*heim_db_plug_commit_f_t
)(void *, heim_error_t
*);
387 typedef int (*heim_db_plug_rollback_f_t
)(void *, heim_error_t
*);
388 typedef heim_data_t (*heim_db_plug_copy_value_f_t
)(void *, heim_string_t
,
391 typedef int (*heim_db_plug_set_value_f_t
)(void *, heim_string_t
, heim_data_t
,
392 heim_data_t
, heim_error_t
*);
393 typedef int (*heim_db_plug_del_key_f_t
)(void *, heim_string_t
, heim_data_t
,
395 typedef void (*heim_db_plug_iter_f_t
)(void *, heim_string_t
, void *,
396 heim_db_iterator_f_t
, heim_error_t
*);
398 struct heim_db_type
{
400 heim_db_plug_open_f_t openf
;
401 heim_db_plug_clone_f_t clonef
;
402 heim_db_plug_close_f_t closef
;
403 heim_db_plug_lock_f_t lockf
;
404 heim_db_plug_unlock_f_t unlockf
;
405 heim_db_plug_sync_f_t syncf
;
406 heim_db_plug_begin_f_t beginf
;
407 heim_db_plug_commit_f_t commitf
;
408 heim_db_plug_rollback_f_t rollbackf
;
409 heim_db_plug_copy_value_f_t copyf
;
410 heim_db_plug_set_value_f_t setf
;
411 heim_db_plug_del_key_f_t delf
;
412 heim_db_plug_iter_f_t iterf
;
415 extern struct heim_db_type heim_sorted_text_file_dbtype
;
417 #define HEIM_DB_TYPE_VERSION_01 1
419 int heim_db_register(const char *dbtype
,
421 struct heim_db_type
*plugin
);
423 heim_db_t
heim_db_create(const char *dbtype
, const char *dbname
,
424 heim_dict_t options
, heim_error_t
*error
);
425 heim_db_t
heim_db_clone(heim_db_t
, heim_error_t
*);
426 int heim_db_begin(heim_db_t
, int, heim_error_t
*);
427 int heim_db_commit(heim_db_t
, heim_error_t
*);
428 int heim_db_rollback(heim_db_t
, heim_error_t
*);
429 heim_tid_t
heim_db_get_type_id(void);
431 int heim_db_set_value(heim_db_t
, heim_string_t
, heim_data_t
, heim_data_t
,
433 heim_data_t
heim_db_copy_value(heim_db_t
, heim_string_t
, heim_data_t
,
435 int heim_db_delete_key(heim_db_t
, heim_string_t
, heim_data_t
,
437 void heim_db_iterate_f(heim_db_t
, heim_string_t
, void *,
438 heim_db_iterator_f_t
, heim_error_t
*);
440 void heim_db_iterate(heim_db_t
, heim_string_t
,
441 void (^)(heim_data_t
, heim_data_t
), heim_error_t
*);
449 typedef struct heim_number_data
*heim_number_t
;
451 heim_number_t
heim_number_create(int);
452 heim_tid_t
heim_number_get_type_id(void);
453 int heim_number_get_int(heim_number_t
);
459 typedef struct heim_auto_release
* heim_auto_release_t
;
461 heim_auto_release_t
heim_auto_release_create(void);
462 void heim_auto_release_drain(heim_auto_release_t
);
463 heim_object_t
heim_auto_release(heim_object_t
);
468 typedef enum heim_json_flags
{
469 HEIM_JSON_F_NO_C_NULL
= 1,
470 HEIM_JSON_F_STRICT_STRINGS
= 2,
471 HEIM_JSON_F_NO_DATA
= 4,
472 HEIM_JSON_F_NO_DATA_DICT
= 8,
473 HEIM_JSON_F_STRICT_DICT
= 16,
474 HEIM_JSON_F_STRICT
= 31,
475 HEIM_JSON_F_CNULL2JSNULL
= 32,
476 HEIM_JSON_F_TRY_DECODE_DATA
= 64,
477 HEIM_JSON_F_ONE_LINE
= 128
480 heim_object_t
heim_json_create(const char *, size_t, heim_json_flags_t
,
482 heim_object_t
heim_json_create_with_bytes(const void *, size_t, size_t,
485 heim_string_t
heim_json_copy_serialize(heim_object_t
, heim_json_flags_t
,
494 heim_description(heim_object_t ptr
);
499 * Note: these are private until integrated into the heimbase object system.
501 typedef struct bsearch_file_handle
*bsearch_file_handle
;
502 int _bsearch_text(const char *buf
, size_t buf_sz
, const char *key
,
503 char **value
, size_t *location
, size_t *loops
);
504 int _bsearch_file_open(const char *fname
, size_t max_sz
, size_t page_sz
,
505 bsearch_file_handle
*bfh
, size_t *reads
);
506 int _bsearch_file(bsearch_file_handle bfh
, const char *key
, char **value
,
507 size_t *location
, size_t *loops
, size_t *reads
);
508 void _bsearch_file_info(bsearch_file_handle bfh
, size_t *page_sz
,
509 size_t *max_sz
, int *blockwise
);
510 void _bsearch_file_close(bsearch_file_handle
*bfh
);
513 * Thread-specific keys
516 int heim_w32_key_create(unsigned long *, void (*)(void *));
517 int heim_w32_delete_key(unsigned long);
518 int heim_w32_setspecific(unsigned long, void *);
519 void *heim_w32_getspecific(unsigned long);
520 void heim_w32_service_thread_detach(void *);
526 #if defined(__GNUC__) && defined(HAVE___SYNC_ADD_AND_FETCH)
528 #define heim_base_atomic_inc(x) __sync_add_and_fetch((x), 1)
529 #define heim_base_atomic_dec(x) __sync_sub_and_fetch((x), 1)
530 #define heim_base_atomic_type unsigned int
531 #define heim_base_atomic_max UINT_MAX
533 #ifndef __has_builtin
534 #define __has_builtin(x) 0
537 #if __has_builtin(__sync_swap)
538 #define heim_base_exchange_pointer(t,v) __sync_swap((t), (v))
540 #define heim_base_exchange_pointer(t,v) __sync_lock_test_and_set((t), (v))
543 #define heim_base_exchange_32(t,v) heim_base_exchange_pointer((t), (v))
544 #define heim_base_exchange_64(t,v) heim_base_exchange_pointer((t), (v))
548 #include <sys/atomic.h>
550 #define heim_base_atomic_inc(x) atomic_inc_uint_nv((volatile uint_t *)(x))
551 #define heim_base_atomic_dec(x) atomic_dec_uint_nv((volatile uint_t *)(x))
552 #define heim_base_atomic_type uint_t
553 #define heim_base_atomic_max UINT_MAX
555 #define heim_base_exchange_pointer(t,v) atomic_swap_ptr((volatile void *)(t), (void *)(v))
556 #define heim_base_exchange_32(t,v) atomic_swap_32((volatile uint32_t *)(t), (v))
557 #define heim_base_exchange_64(t,v) atomic_swap_64((volatile uint64_t *)(t), (v))
561 #include <sys/atomic_op.h>
563 #define heim_base_atomic_inc(x) (fetch_and_add((atomic_p)(x)) + 1)
564 #define heim_base_atomic_dec(x) (fetch_and_add((atomic_p)(x)) - 1)
565 #define heim_base_atomic_type unsigned int
566 #define heim_base_atomic_max UINT_MAX
569 heim_base_exchange_pointer(void *p
, void *newval
)
571 void *val
= *(void **)p
;
573 while (!compare_and_swaplp((atomic_l
)p
, (long *)&val
, (long)newval
))
579 static inline uint32_t
580 heim_base_exchange_32(uint32_t *p
, uint32_t newval
)
584 while (!compare_and_swap((atomic_p
)p
, (int *)&val
, (int)newval
))
590 static inline uint64_t
591 heim_base_exchange_64(uint64_t *p
, uint64_t newval
)
595 while (!compare_and_swaplp((atomic_l
)p
, (long *)&val
, (long)newval
))
601 #elif defined(_WIN32)
603 #define heim_base_atomic_inc(x) InterlockedIncrement(x)
604 #define heim_base_atomic_dec(x) InterlockedDecrement(x)
605 #define heim_base_atomic_type LONG
606 #define heim_base_atomic_max MAXLONG
608 #define heim_base_exchange_pointer(t,v) InterlockedExchangePointer((PVOID volatile *)(t), (PVOID)(v))
609 #define heim_base_exchange_32(t,v) ((ULONG)InterlockedExchange((LONG volatile *)(t), (LONG)(v)))
610 #define heim_base_exchange_64(t,v) ((ULONG64)InterlockedExchange64((LONG64 violatile *)(t), (LONG64)(v)))
614 #include "heim_threads.h"
616 #define HEIM_BASE_NEED_ATOMIC_MUTEX 1
617 extern HEIMDAL_MUTEX _heim_base_mutex
;
619 #define heim_base_atomic_type unsigned int
621 static inline heim_base_atomic_type
622 heim_base_atomic_inc(heim_base_atomic_type
*x
)
624 heim_base_atomic_type t
;
625 HEIMDAL_MUTEX_lock(&_heim_base_mutex
);
627 HEIMDAL_MUTEX_unlock(&_heim_base_mutex
);
631 static inline heim_base_atomic_type
632 heim_base_atomic_dec(heim_base_atomic_type
*x
)
634 heim_base_atomic_type t
;
635 HEIMDAL_MUTEX_lock(&_heim_base_mutex
);
637 HEIMDAL_MUTEX_unlock(&_heim_base_mutex
);
641 #define heim_base_atomic_max UINT_MAX
644 heim_base_exchange_pointer(void *target
, void *value
)
647 HEIMDAL_MUTEX_lock(&_heim_base_mutex
);
648 old
= *(void **)target
;
649 *(void **)target
= value
;
650 HEIMDAL_MUTEX_unlock(&_heim_base_mutex
);
654 #endif /* defined(__GNUC__) && defined(HAVE___SYNC_ADD_AND_FETCH) */
656 #if SIZEOF_TIME_T == 8
657 #define heim_base_exchange_time_t(t,v) heim_base_exchange_64((t), (v))
658 #elif SIZEOF_TIME_T == 4
659 #define heim_base_exchange_time_t(t,v) heim_base_exchange_32((t), (v))
661 #error set SIZEOF_TIME_T for your platform
664 #include <heim_threads.h>
668 * Service logging facility (moved from kdc/).
671 #define HEIM_SVC_AUDIT_EATWHITE 0x1
672 #define HEIM_SVC_AUDIT_VIS 0x2
673 #define HEIM_SVC_AUDIT_VISLAST 0x4
675 typedef struct heim_svc_req_desc_common_s
*heim_svc_req_desc
;
677 #include <heimbase-protos.h>
679 #endif /* HEIM_BASE_H */