summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2018-09-13 13:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2018-09-13 13:03:10 +0000
commit7b0449b51cafff37d132c8b08764ba13c7617feb (patch)
treec39a198a237d6b4229ea0b8c189a420bfa4f2b17
parentReleasing progress-linux version 2:1.4.0-1~dschinn1. (diff)
downloadldb-7b0449b51cafff37d132c8b08764ba13c7617feb.zip
ldb-7b0449b51cafff37d132c8b08764ba13c7617feb.tar.xz
Merging upstream version 2:1.4.0+really1.3.5.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--ABI/ldb-1.3.3.sigs (renamed from ABI/ldb-1.4.0.sigs)0
-rw-r--r--ABI/ldb-1.3.4.sigs279
-rw-r--r--ABI/ldb-1.3.5.sigs279
-rw-r--r--ABI/pyldb-util-1.3.3.sigs (renamed from ABI/pyldb-util-1.4.0.sigs)0
-rw-r--r--ABI/pyldb-util-1.3.4.sigs (renamed from ABI/pyldb-util.py3-1.4.0.sigs)0
-rw-r--r--ABI/pyldb-util-1.3.5.sigs2
-rw-r--r--ABI/pyldb-util.py3-1.3.3.sigs2
-rw-r--r--ABI/pyldb-util.py3-1.3.4.sigs2
-rw-r--r--ABI/pyldb-util.py3-1.3.5.sigs2
-rw-r--r--buildtools/wafsamba/nothreads.py4
-rw-r--r--buildtools/wafsamba/samba_autoconf.py4
-rw-r--r--buildtools/wafsamba/samba_conftests.py2
-rw-r--r--buildtools/wafsamba/samba_dist.py2
-rw-r--r--buildtools/wafsamba/samba_version.py2
-rw-r--r--buildtools/wafsamba/wafsamba.py7
-rw-r--r--common/ldb.c3
-rw-r--r--common/ldb_dn.c3
-rw-r--r--common/ldb_ldif.c6
-rw-r--r--common/ldb_modules.c2
-rw-r--r--common/qsort.c10
-rw-r--r--ldb_ldb/ldb_ldb.c80
-rw-r--r--ldb_map/ldb_map.c6
-rw-r--r--ldb_map/ldb_map_inbound.c6
-rw-r--r--ldb_map/ldb_map_outbound.c3
-rw-r--r--ldb_mdb/ldb_mdb.c887
-rw-r--r--ldb_mdb/ldb_mdb.h60
-rw-r--r--ldb_mdb/ldb_mdb_init.c31
-rw-r--r--ldb_sqlite3/ldb_sqlite3.c3
-rw-r--r--ldb_tdb/ldb_cache.c74
-rw-r--r--ldb_tdb/ldb_index.c510
-rw-r--r--ldb_tdb/ldb_search.c110
-rw-r--r--ldb_tdb/ldb_tdb.c603
-rw-r--r--ldb_tdb/ldb_tdb.h71
-rw-r--r--ldb_tdb/ldb_tdb_init.c59
-rw-r--r--ldb_tdb/ldb_tdb_wrap.c18
-rw-r--r--lib/replace/replace.h9
-rw-r--r--lib/replace/strptime.c6
-rw-r--r--lib/replace/system/wscript_configure8
-rw-r--r--lib/replace/wscript42
-rw-r--r--lib/talloc/ABI/pytalloc-util-2.1.12.sigs16
-rw-r--r--lib/talloc/ABI/pytalloc-util-2.1.13.sigs16
-rw-r--r--lib/talloc/ABI/pytalloc-util.py3-2.1.12.sigs15
-rw-r--r--lib/talloc/ABI/pytalloc-util.py3-2.1.13.sigs15
-rw-r--r--lib/talloc/ABI/talloc-2.1.12.sigs65
-rw-r--r--lib/talloc/ABI/talloc-2.1.13.sigs65
-rw-r--r--lib/talloc/pytalloc.c2
-rw-r--r--lib/talloc/talloc.c75
-rw-r--r--lib/talloc/talloc.h6
-rw-r--r--lib/talloc/wscript4
-rw-r--r--lib/tdb/common/check.c17
-rw-r--r--lib/tdb/common/hash.c50
-rw-r--r--lib/tdb/common/io.c28
-rw-r--r--lib/tdb/common/open.c15
-rw-r--r--lib/tdb/common/summary.c3
-rw-r--r--lib/tdb/common/transaction.c25
-rw-r--r--lib/tdb/common/traverse.c13
-rw-r--r--lib/tdb/python/tdbdump.py7
-rw-r--r--lib/tdb/tools/tdbdump.c4
-rw-r--r--lib/tdb/tools/tdbtool.c11
-rw-r--r--lib/tevent/pytevent.c2
-rw-r--r--lib/tevent/testsuite.c5
-rw-r--r--lib/tevent/tevent.h3
-rw-r--r--modules/paged_results.c43
-rw-r--r--pyldb.c16
-rw-r--r--pyldb_util.c2
-rw-r--r--tests/ldb_kv_ops_test.c1576
-rw-r--r--tests/ldb_lmdb_size_test.c210
-rw-r--r--tests/ldb_lmdb_test.c588
-rw-r--r--tests/ldb_mod_op_test.c706
-rw-r--r--tests/ldb_tdb_test.c387
-rwxr-xr-xtests/python/api.py428
-rwxr-xr-xtests/python/index.py320
-rw-r--r--tests/test_ldb_qsort.c64
-rw-r--r--third_party/cmocka/cmocka.c26
-rw-r--r--third_party/cmocka/cmocka.h2
-rw-r--r--third_party/popt/README10
-rw-r--r--third_party/popt/dummy.in0
-rw-r--r--third_party/popt/findme.c50
-rw-r--r--third_party/popt/lookup3.c969
-rw-r--r--third_party/popt/popt.c1428
-rw-r--r--third_party/popt/popt.h333
-rw-r--r--third_party/popt/poptconfig.c598
-rw-r--r--third_party/popt/popthelp.c706
-rw-r--r--third_party/popt/poptint.c199
-rw-r--r--third_party/popt/poptint.h130
-rw-r--r--third_party/popt/poptparse.c69
-rw-r--r--third_party/popt/system.h87
-rw-r--r--third_party/popt/wscript6
-rw-r--r--tools/ldbdump.c126
-rw-r--r--wscript205
90 files changed, 2339 insertions, 10604 deletions
diff --git a/ABI/ldb-1.4.0.sigs b/ABI/ldb-1.3.3.sigs
index a31b84e..a31b84e 100644
--- a/ABI/ldb-1.4.0.sigs
+++ b/ABI/ldb-1.3.3.sigs
diff --git a/ABI/ldb-1.3.4.sigs b/ABI/ldb-1.3.4.sigs
new file mode 100644
index 0000000..a31b84e
--- /dev/null
+++ b/ABI/ldb-1.3.4.sigs
@@ -0,0 +1,279 @@
+ldb_add: int (struct ldb_context *, const struct ldb_message *)
+ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *)
+ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...)
+ldb_attr_casefold: char *(TALLOC_CTX *, const char *)
+ldb_attr_dn: int (const char *)
+ldb_attr_in_list: int (const char * const *, const char *)
+ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *)
+ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *)
+ldb_base64_decode: int (char *)
+ldb_base64_encode: char *(TALLOC_CTX *, const char *, int)
+ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *)
+ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val)
+ldb_binary_encode_string: char *(TALLOC_CTX *, const char *)
+ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t)
+ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t)
+ldb_check_critical_controls: int (struct ldb_control **)
+ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *)
+ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *)
+ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **)
+ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *)
+ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *)
+ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...)
+ldb_debug_add: void (struct ldb_context *, const char *, ...)
+ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level)
+ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...)
+ldb_delete: int (struct ldb_context *, struct ldb_dn *)
+ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...)
+ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...)
+ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *)
+ldb_dn_check_special: bool (struct ldb_dn *, const char *)
+ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val)
+ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *)
+ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *)
+ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *)
+ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *)
+ldb_dn_get_casefold: const char *(struct ldb_dn *)
+ldb_dn_get_comp_num: int (struct ldb_dn *)
+ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int)
+ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int)
+ldb_dn_get_extended_comp_num: int (struct ldb_dn *)
+ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *)
+ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int)
+ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *)
+ldb_dn_get_linearized: const char *(struct ldb_dn *)
+ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_get_rdn_name: const char *(struct ldb_dn *)
+ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *)
+ldb_dn_has_extended: bool (struct ldb_dn *)
+ldb_dn_is_null: bool (struct ldb_dn *)
+ldb_dn_is_special: bool (struct ldb_dn *)
+ldb_dn_is_valid: bool (struct ldb_dn *)
+ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *)
+ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *)
+ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *)
+ldb_dn_minimise: bool (struct ldb_dn *)
+ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *)
+ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...)
+ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int)
+ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int)
+ldb_dn_remove_extended_components: void (struct ldb_dn *)
+ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val)
+ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *)
+ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *)
+ldb_dn_validate: bool (struct ldb_dn *)
+ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *)
+ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int)
+ldb_errstring: const char *(struct ldb_context *)
+ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **)
+ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *)
+ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_get_create_perms: unsigned int (struct ldb_context *)
+ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_get_event_context: struct tevent_context *(struct ldb_context *)
+ldb_get_flags: unsigned int (struct ldb_context *)
+ldb_get_opaque: void *(struct ldb_context *, const char *)
+ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_global_init: int (void)
+ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *)
+ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *)
+ldb_handle_use_global_event_context: void (struct ldb_handle *)
+ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *)
+ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *)
+ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *)
+ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *)
+ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *)
+ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **)
+ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *)
+ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *)
+ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *)
+ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *)
+ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **)
+ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *)
+ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *)
+ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *)
+ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *)
+ldb_load_modules: int (struct ldb_context *, const char **)
+ldb_map_add: int (struct ldb_module *, struct ldb_request *)
+ldb_map_delete: int (struct ldb_module *, struct ldb_request *)
+ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *)
+ldb_map_modify: int (struct ldb_module *, struct ldb_request *)
+ldb_map_rename: int (struct ldb_module *, struct ldb_request *)
+ldb_map_search: int (struct ldb_module *, struct ldb_request *)
+ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *)
+ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope)
+ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *)
+ldb_match_msg_objectclass: int (const struct ldb_message *, const char *)
+ldb_mod_register_control: int (struct ldb_module *, const char *)
+ldb_modify: int (struct ldb_context *, const struct ldb_message *)
+ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *)
+ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **)
+ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int)
+ldb_module_flags: uint32_t (struct ldb_context *)
+ldb_module_get_ctx: struct ldb_context *(struct ldb_module *)
+ldb_module_get_name: const char *(struct ldb_module *)
+ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *)
+ldb_module_get_private: void *(struct ldb_module *)
+ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *)
+ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **)
+ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *)
+ldb_module_next: struct ldb_module *(struct ldb_module *)
+ldb_module_popt_options: struct poptOption **(struct ldb_context *)
+ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **)
+ldb_module_send_referral: int (struct ldb_request *, char *)
+ldb_module_set_next: void (struct ldb_module *, struct ldb_module *)
+ldb_module_set_private: void (struct ldb_module *, void *)
+ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type)
+ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *)
+ldb_modules_load: int (const char *, const char *)
+ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int)
+ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **)
+ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...)
+ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *)
+ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *)
+ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *)
+ldb_msg_add_string: int (struct ldb_message *, const char *, const char *)
+ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **)
+ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *)
+ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *)
+ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *)
+ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *)
+ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *)
+ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *)
+ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **)
+ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *)
+ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *)
+ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *)
+ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int)
+ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *)
+ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double)
+ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int)
+ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t)
+ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *)
+ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int)
+ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t)
+ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t)
+ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t)
+ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *)
+ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *)
+ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *)
+ldb_msg_new: struct ldb_message *(TALLOC_CTX *)
+ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **)
+ldb_msg_remove_attr: void (struct ldb_message *, const char *)
+ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *)
+ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *)
+ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *)
+ldb_msg_sort_elements: void (struct ldb_message *)
+ldb_next_del_trans: int (struct ldb_module *)
+ldb_next_end_trans: int (struct ldb_module *)
+ldb_next_init: int (struct ldb_module *)
+ldb_next_prepare_commit: int (struct ldb_module *)
+ldb_next_read_lock: int (struct ldb_module *)
+ldb_next_read_unlock: int (struct ldb_module *)
+ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *)
+ldb_next_request: int (struct ldb_module *, struct ldb_request *)
+ldb_next_start_trans: int (struct ldb_module *)
+ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_options_find: const char *(struct ldb_context *, const char **, const char *)
+ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *)
+ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *)
+ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **)
+ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *)
+ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *)
+ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *)
+ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *)
+ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t)
+ldb_register_backend: int (const char *, ldb_connect_fn, bool)
+ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *)
+ldb_register_hook: int (ldb_hook_fn)
+ldb_register_module: int (const struct ldb_module_ops *)
+ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *)
+ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *)
+ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *)
+ldb_req_get_custom_flags: uint32_t (struct ldb_request *)
+ldb_req_is_untrusted: bool (struct ldb_request *)
+ldb_req_location: const char *(struct ldb_request *)
+ldb_req_mark_trusted: void (struct ldb_request *)
+ldb_req_mark_untrusted: void (struct ldb_request *)
+ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t)
+ldb_req_set_location: void (struct ldb_request *, const char *)
+ldb_request: int (struct ldb_context *, struct ldb_request *)
+ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *)
+ldb_request_done: int (struct ldb_request *, int)
+ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *)
+ldb_request_get_status: int (struct ldb_request *)
+ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *)
+ldb_request_set_state: void (struct ldb_request *, int)
+ldb_reset_err_string: void (struct ldb_context *)
+ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***)
+ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *)
+ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *)
+ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *)
+ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *)
+ldb_schema_attribute_remove: void (struct ldb_context *, const char *)
+ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int)
+ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *)
+ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *)
+ldb_schema_set_override_indexlist: void (struct ldb_context *, bool)
+ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...)
+ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *)
+ldb_set_create_perms: void (struct ldb_context *, unsigned int)
+ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *)
+ldb_set_debug_stderr: int (struct ldb_context *)
+ldb_set_default_dns: void (struct ldb_context *)
+ldb_set_errstring: void (struct ldb_context *, const char *)
+ldb_set_event_context: void (struct ldb_context *, struct tevent_context *)
+ldb_set_flags: void (struct ldb_context *, unsigned int)
+ldb_set_modules_dir: void (struct ldb_context *, const char *)
+ldb_set_opaque: int (struct ldb_context *, const char *, void *)
+ldb_set_require_private_event_context: void (struct ldb_context *)
+ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int)
+ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *)
+ldb_set_utf8_default: void (struct ldb_context *)
+ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t))
+ldb_setup_wellknown_attributes: int (struct ldb_context *)
+ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *)
+ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *)
+ldb_strerror: const char *(int)
+ldb_string_to_time: time_t (const char *)
+ldb_string_utc_to_time: time_t (const char *)
+ldb_timestring: char *(TALLOC_CTX *, time_t)
+ldb_timestring_utc: char *(TALLOC_CTX *, time_t)
+ldb_transaction_cancel: int (struct ldb_context *)
+ldb_transaction_cancel_noerr: int (struct ldb_context *)
+ldb_transaction_commit: int (struct ldb_context *)
+ldb_transaction_prepare_commit: int (struct ldb_context *)
+ldb_transaction_start: int (struct ldb_context *)
+ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *)
+ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *)
+ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *)
+ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *)
+ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *)
+ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *)
+ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *)
+ldb_val_string_cmp: int (const struct ldb_val *, const char *)
+ldb_val_to_time: int (const struct ldb_val *, time_t *)
+ldb_valid_attr_name: int (const char *)
+ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list)
+ldb_wait: int (struct ldb_handle *, enum ldb_wait_type)
diff --git a/ABI/ldb-1.3.5.sigs b/ABI/ldb-1.3.5.sigs
new file mode 100644
index 0000000..a31b84e
--- /dev/null
+++ b/ABI/ldb-1.3.5.sigs
@@ -0,0 +1,279 @@
+ldb_add: int (struct ldb_context *, const struct ldb_message *)
+ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *)
+ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...)
+ldb_attr_casefold: char *(TALLOC_CTX *, const char *)
+ldb_attr_dn: int (const char *)
+ldb_attr_in_list: int (const char * const *, const char *)
+ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *)
+ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *)
+ldb_base64_decode: int (char *)
+ldb_base64_encode: char *(TALLOC_CTX *, const char *, int)
+ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *)
+ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val)
+ldb_binary_encode_string: char *(TALLOC_CTX *, const char *)
+ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t)
+ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t)
+ldb_check_critical_controls: int (struct ldb_control **)
+ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *)
+ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *)
+ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **)
+ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *)
+ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *)
+ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...)
+ldb_debug_add: void (struct ldb_context *, const char *, ...)
+ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level)
+ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...)
+ldb_delete: int (struct ldb_context *, struct ldb_dn *)
+ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...)
+ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...)
+ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *)
+ldb_dn_check_special: bool (struct ldb_dn *, const char *)
+ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val)
+ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *)
+ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *)
+ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *)
+ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *)
+ldb_dn_get_casefold: const char *(struct ldb_dn *)
+ldb_dn_get_comp_num: int (struct ldb_dn *)
+ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int)
+ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int)
+ldb_dn_get_extended_comp_num: int (struct ldb_dn *)
+ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *)
+ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int)
+ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *)
+ldb_dn_get_linearized: const char *(struct ldb_dn *)
+ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_get_rdn_name: const char *(struct ldb_dn *)
+ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *)
+ldb_dn_has_extended: bool (struct ldb_dn *)
+ldb_dn_is_null: bool (struct ldb_dn *)
+ldb_dn_is_special: bool (struct ldb_dn *)
+ldb_dn_is_valid: bool (struct ldb_dn *)
+ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *)
+ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *)
+ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *)
+ldb_dn_minimise: bool (struct ldb_dn *)
+ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *)
+ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...)
+ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int)
+ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int)
+ldb_dn_remove_extended_components: void (struct ldb_dn *)
+ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val)
+ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *)
+ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *)
+ldb_dn_validate: bool (struct ldb_dn *)
+ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *)
+ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int)
+ldb_errstring: const char *(struct ldb_context *)
+ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **)
+ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *)
+ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_get_create_perms: unsigned int (struct ldb_context *)
+ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_get_event_context: struct tevent_context *(struct ldb_context *)
+ldb_get_flags: unsigned int (struct ldb_context *)
+ldb_get_opaque: void *(struct ldb_context *, const char *)
+ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_global_init: int (void)
+ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *)
+ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *)
+ldb_handle_use_global_event_context: void (struct ldb_handle *)
+ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *)
+ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *)
+ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *)
+ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *)
+ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *)
+ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **)
+ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *)
+ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *)
+ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *)
+ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *)
+ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **)
+ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *)
+ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *)
+ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *)
+ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *)
+ldb_load_modules: int (struct ldb_context *, const char **)
+ldb_map_add: int (struct ldb_module *, struct ldb_request *)
+ldb_map_delete: int (struct ldb_module *, struct ldb_request *)
+ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *)
+ldb_map_modify: int (struct ldb_module *, struct ldb_request *)
+ldb_map_rename: int (struct ldb_module *, struct ldb_request *)
+ldb_map_search: int (struct ldb_module *, struct ldb_request *)
+ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *)
+ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope)
+ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *)
+ldb_match_msg_objectclass: int (const struct ldb_message *, const char *)
+ldb_mod_register_control: int (struct ldb_module *, const char *)
+ldb_modify: int (struct ldb_context *, const struct ldb_message *)
+ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *)
+ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **)
+ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int)
+ldb_module_flags: uint32_t (struct ldb_context *)
+ldb_module_get_ctx: struct ldb_context *(struct ldb_module *)
+ldb_module_get_name: const char *(struct ldb_module *)
+ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *)
+ldb_module_get_private: void *(struct ldb_module *)
+ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *)
+ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **)
+ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *)
+ldb_module_next: struct ldb_module *(struct ldb_module *)
+ldb_module_popt_options: struct poptOption **(struct ldb_context *)
+ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **)
+ldb_module_send_referral: int (struct ldb_request *, char *)
+ldb_module_set_next: void (struct ldb_module *, struct ldb_module *)
+ldb_module_set_private: void (struct ldb_module *, void *)
+ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type)
+ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *)
+ldb_modules_load: int (const char *, const char *)
+ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int)
+ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **)
+ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...)
+ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *)
+ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *)
+ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *)
+ldb_msg_add_string: int (struct ldb_message *, const char *, const char *)
+ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **)
+ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *)
+ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *)
+ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *)
+ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *)
+ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *)
+ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *)
+ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **)
+ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *)
+ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *)
+ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *)
+ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int)
+ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *)
+ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double)
+ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int)
+ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t)
+ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *)
+ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int)
+ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t)
+ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t)
+ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t)
+ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *)
+ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *)
+ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *)
+ldb_msg_new: struct ldb_message *(TALLOC_CTX *)
+ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **)
+ldb_msg_remove_attr: void (struct ldb_message *, const char *)
+ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *)
+ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *)
+ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *)
+ldb_msg_sort_elements: void (struct ldb_message *)
+ldb_next_del_trans: int (struct ldb_module *)
+ldb_next_end_trans: int (struct ldb_module *)
+ldb_next_init: int (struct ldb_module *)
+ldb_next_prepare_commit: int (struct ldb_module *)
+ldb_next_read_lock: int (struct ldb_module *)
+ldb_next_read_unlock: int (struct ldb_module *)
+ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *)
+ldb_next_request: int (struct ldb_module *, struct ldb_request *)
+ldb_next_start_trans: int (struct ldb_module *)
+ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_options_find: const char *(struct ldb_context *, const char **, const char *)
+ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *)
+ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *)
+ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **)
+ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *)
+ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *)
+ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *)
+ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *)
+ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t)
+ldb_register_backend: int (const char *, ldb_connect_fn, bool)
+ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *)
+ldb_register_hook: int (ldb_hook_fn)
+ldb_register_module: int (const struct ldb_module_ops *)
+ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *)
+ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *)
+ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *)
+ldb_req_get_custom_flags: uint32_t (struct ldb_request *)
+ldb_req_is_untrusted: bool (struct ldb_request *)
+ldb_req_location: const char *(struct ldb_request *)
+ldb_req_mark_trusted: void (struct ldb_request *)
+ldb_req_mark_untrusted: void (struct ldb_request *)
+ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t)
+ldb_req_set_location: void (struct ldb_request *, const char *)
+ldb_request: int (struct ldb_context *, struct ldb_request *)
+ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *)
+ldb_request_done: int (struct ldb_request *, int)
+ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *)
+ldb_request_get_status: int (struct ldb_request *)
+ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *)
+ldb_request_set_state: void (struct ldb_request *, int)
+ldb_reset_err_string: void (struct ldb_context *)
+ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***)
+ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *)
+ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *)
+ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *)
+ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *)
+ldb_schema_attribute_remove: void (struct ldb_context *, const char *)
+ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int)
+ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *)
+ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *)
+ldb_schema_set_override_indexlist: void (struct ldb_context *, bool)
+ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...)
+ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *)
+ldb_set_create_perms: void (struct ldb_context *, unsigned int)
+ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *)
+ldb_set_debug_stderr: int (struct ldb_context *)
+ldb_set_default_dns: void (struct ldb_context *)
+ldb_set_errstring: void (struct ldb_context *, const char *)
+ldb_set_event_context: void (struct ldb_context *, struct tevent_context *)
+ldb_set_flags: void (struct ldb_context *, unsigned int)
+ldb_set_modules_dir: void (struct ldb_context *, const char *)
+ldb_set_opaque: int (struct ldb_context *, const char *, void *)
+ldb_set_require_private_event_context: void (struct ldb_context *)
+ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int)
+ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *)
+ldb_set_utf8_default: void (struct ldb_context *)
+ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t))
+ldb_setup_wellknown_attributes: int (struct ldb_context *)
+ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *)
+ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *)
+ldb_strerror: const char *(int)
+ldb_string_to_time: time_t (const char *)
+ldb_string_utc_to_time: time_t (const char *)
+ldb_timestring: char *(TALLOC_CTX *, time_t)
+ldb_timestring_utc: char *(TALLOC_CTX *, time_t)
+ldb_transaction_cancel: int (struct ldb_context *)
+ldb_transaction_cancel_noerr: int (struct ldb_context *)
+ldb_transaction_commit: int (struct ldb_context *)
+ldb_transaction_prepare_commit: int (struct ldb_context *)
+ldb_transaction_start: int (struct ldb_context *)
+ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *)
+ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *)
+ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *)
+ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *)
+ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *)
+ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *)
+ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *)
+ldb_val_string_cmp: int (const struct ldb_val *, const char *)
+ldb_val_to_time: int (const struct ldb_val *, time_t *)
+ldb_valid_attr_name: int (const char *)
+ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list)
+ldb_wait: int (struct ldb_handle *, enum ldb_wait_type)
diff --git a/ABI/pyldb-util-1.4.0.sigs b/ABI/pyldb-util-1.3.3.sigs
index 74d6719..74d6719 100644
--- a/ABI/pyldb-util-1.4.0.sigs
+++ b/ABI/pyldb-util-1.3.3.sigs
diff --git a/ABI/pyldb-util.py3-1.4.0.sigs b/ABI/pyldb-util-1.3.4.sigs
index 74d6719..74d6719 100644
--- a/ABI/pyldb-util.py3-1.4.0.sigs
+++ b/ABI/pyldb-util-1.3.4.sigs
diff --git a/ABI/pyldb-util-1.3.5.sigs b/ABI/pyldb-util-1.3.5.sigs
new file mode 100644
index 0000000..74d6719
--- /dev/null
+++ b/ABI/pyldb-util-1.3.5.sigs
@@ -0,0 +1,2 @@
+pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
+pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
diff --git a/ABI/pyldb-util.py3-1.3.3.sigs b/ABI/pyldb-util.py3-1.3.3.sigs
new file mode 100644
index 0000000..74d6719
--- /dev/null
+++ b/ABI/pyldb-util.py3-1.3.3.sigs
@@ -0,0 +1,2 @@
+pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
+pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
diff --git a/ABI/pyldb-util.py3-1.3.4.sigs b/ABI/pyldb-util.py3-1.3.4.sigs
new file mode 100644
index 0000000..74d6719
--- /dev/null
+++ b/ABI/pyldb-util.py3-1.3.4.sigs
@@ -0,0 +1,2 @@
+pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
+pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
diff --git a/ABI/pyldb-util.py3-1.3.5.sigs b/ABI/pyldb-util.py3-1.3.5.sigs
new file mode 100644
index 0000000..74d6719
--- /dev/null
+++ b/ABI/pyldb-util.py3-1.3.5.sigs
@@ -0,0 +1,2 @@
+pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
+pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
diff --git a/buildtools/wafsamba/nothreads.py b/buildtools/wafsamba/nothreads.py
index 9bd33e8..d194eb8 100644
--- a/buildtools/wafsamba/nothreads.py
+++ b/buildtools/wafsamba/nothreads.py
@@ -43,7 +43,7 @@ def process(tsk):
if tsk.__class__.stat: ret = tsk.__class__.stat(tsk)
# actual call to task's run() function
else: ret = tsk.call_run()
- except Exception as e:
+ except Exception, e:
tsk.err_msg = Utils.ex_stack()
tsk.hasrun = EXCEPTION
@@ -177,7 +177,7 @@ class Parallel(object):
try:
st = tsk.runnable_status()
- except Exception as e:
+ except Exception, e:
self.processed += 1
if self.stop and not Options.options.keep:
tsk.hasrun = SKIPPED
diff --git a/buildtools/wafsamba/samba_autoconf.py b/buildtools/wafsamba/samba_autoconf.py
index bdd7c8b..cc08e0d 100644
--- a/buildtools/wafsamba/samba_autoconf.py
+++ b/buildtools/wafsamba/samba_autoconf.py
@@ -711,10 +711,6 @@ def SAMBA_CONFIG_H(conf, path=None):
testflags=True)
conf.ADD_CFLAGS('-Werror=uninitialized -Wuninitialized',
testflags=True)
- conf.ADD_CFLAGS('-Wimplicit-fallthrough',
- testflags=True)
- conf.ADD_CFLAGS('-Werror=strict-overflow -Wstrict-overflow=2',
- testflags=True)
conf.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags=True)
conf.ADD_CFLAGS('-Wno-format-zero-length', testflags=True)
diff --git a/buildtools/wafsamba/samba_conftests.py b/buildtools/wafsamba/samba_conftests.py
index b52727b..511176d 100644
--- a/buildtools/wafsamba/samba_conftests.py
+++ b/buildtools/wafsamba/samba_conftests.py
@@ -50,7 +50,7 @@ def check(self, *k, **kw):
ret = None
try:
ret = self.run_c_code(*k, **kw)
- except Configure.ConfigurationError as e:
+ except Configure.ConfigurationError, e:
self.check_message_2(kw['errmsg'], 'YELLOW')
if 'mandatory' in kw and kw['mandatory']:
if Logs.verbose > 1:
diff --git a/buildtools/wafsamba/samba_dist.py b/buildtools/wafsamba/samba_dist.py
index 8d51632..2e52820 100644
--- a/buildtools/wafsamba/samba_dist.py
+++ b/buildtools/wafsamba/samba_dist.py
@@ -167,7 +167,7 @@ def dist(appname='', version=''):
absdir = os.path.join(srcdir, dir)
try:
files = vcs_dir_contents(absdir)
- except Exception as e:
+ except Exception, e:
Logs.error('unable to get contents of %s: %s' % (absdir, e))
sys.exit(1)
add_files_to_tarball(tar, srcdir, dir, dist_base, destdir, blacklist, files)
diff --git a/buildtools/wafsamba/samba_version.py b/buildtools/wafsamba/samba_version.py
index be26439..950a855 100644
--- a/buildtools/wafsamba/samba_version.py
+++ b/buildtools/wafsamba/samba_version.py
@@ -95,7 +95,7 @@ also accepted as dictionary entries here
self.VENDOR_SUFFIX=None
self.VENDOR_PATCH=None
- for a, b in version_dict.items():
+ for a, b in version_dict.iteritems():
if a.startswith("SAMBA_VERSION_"):
setattr(self, a[14:], b)
else:
diff --git a/buildtools/wafsamba/wafsamba.py b/buildtools/wafsamba/wafsamba.py
index 12d5421..4bb19d0 100644
--- a/buildtools/wafsamba/wafsamba.py
+++ b/buildtools/wafsamba/wafsamba.py
@@ -353,7 +353,6 @@ def SAMBA_BINARY(bld, binname, source,
modules=None,
ldflags=None,
cflags='',
- cflags_end=None,
autoproto=None,
use_hostcc=False,
use_global_deps=True,
@@ -411,7 +410,6 @@ def SAMBA_BINARY(bld, binname, source,
deps = deps,
includes = includes,
cflags = pie_cflags,
- cflags_end = cflags_end,
group = subsystem_group,
autoproto = autoproto,
subsystem_name = subsystem_name,
@@ -460,7 +458,6 @@ def SAMBA_MODULE(bld, modname, source,
autoproto=None,
autoproto_extra_source='',
cflags='',
- cflags_end=None,
internal_module=True,
local_include=True,
global_include=True,
@@ -491,7 +488,6 @@ def SAMBA_MODULE(bld, modname, source,
autoproto=autoproto,
autoproto_extra_source=autoproto_extra_source,
cflags=cflags,
- cflags_end=cflags_end,
local_include=local_include,
global_include=global_include,
allow_warnings=allow_warnings,
@@ -531,7 +527,6 @@ def SAMBA_MODULE(bld, modname, source,
deps=deps,
includes=includes,
cflags=cflags,
- cflags_end=cflags_end,
realname = realname,
autoproto = autoproto,
local_include=local_include,
@@ -905,7 +900,7 @@ def INSTALL_DIR(bld, path, chmod=0o755, env=None):
try:
os.makedirs(destpath)
os.chmod(destpath, chmod)
- except OSError as e:
+ except OSError, e:
if not os.path.isdir(destpath):
raise Utils.WafError("Cannot create the folder '%s' (error: %s)" % (path, e))
Build.BuildContext.INSTALL_DIR = INSTALL_DIR
diff --git a/common/ldb.c b/common/ldb.c
index 5525e70..a4d9977 100644
--- a/common/ldb.c
+++ b/common/ldb.c
@@ -379,7 +379,6 @@ int ldb_transaction_start(struct ldb_context *ldb)
"ldb transaction start: %s (%d)",
ldb_strerror(status),
status);
- ldb->transaction_active--;
}
if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s",
@@ -425,8 +424,6 @@ int ldb_transaction_prepare_commit(struct ldb_context *ldb)
return LDB_SUCCESS;
}
- ldb_reset_err_string(ldb);
-
status = next_module->ops->prepare_commit(next_module);
if (status != LDB_SUCCESS) {
ldb->transaction_active--;
diff --git a/common/ldb_dn.c b/common/ldb_dn.c
index dfeb600..b23ee17 100644
--- a/common/ldb_dn.c
+++ b/common/ldb_dn.c
@@ -629,8 +629,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
l++;
break;
}
-
- FALL_THROUGH;
+ /* fall through */
case '\"':
case '<':
case '>':
diff --git a/common/ldb_ldif.c b/common/ldb_ldif.c
index e23b568..b90d27e 100644
--- a/common/ldb_ldif.c
+++ b/common/ldb_ldif.c
@@ -216,8 +216,7 @@ static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *priva
const char *buf, size_t length, int start_pos)
{
size_t i;
- size_t total = 0;
- int ret;
+ int total=0, ret;
for (i=0;i<length;i++) {
ret = fprintf_fn(private_data, "%c", buf[i]);
@@ -281,8 +280,7 @@ static int ldb_ldif_write_trace(struct ldb_context *ldb,
{
TALLOC_CTX *mem_ctx;
unsigned int i, j;
- size_t total = 0;
- int ret;
+ int total=0, ret;
char *p;
const struct ldb_message *msg;
const char * const * secret_attributes = ldb_get_opaque(ldb, LDB_SECRET_ATTRIBUTE_LIST_OPAQUE);
diff --git a/common/ldb_modules.c b/common/ldb_modules.c
index cc067ab..25551e1 100644
--- a/common/ldb_modules.c
+++ b/common/ldb_modules.c
@@ -1103,7 +1103,7 @@ static int ldb_modules_load_dir(const char *modules_dir, const char *version)
*/
void ldb_set_modules_dir(struct ldb_context *ldb, const char *path)
{
- int ret = ldb_modules_load_dir(path, LDB_VERSION);
+ int ret = ldb_modules_load_path(path, LDB_VERSION);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb, "Failed to load modules from: %s\n", path);
}
diff --git a/common/qsort.c b/common/qsort.c
index 012aaf3..1a0b886 100644
--- a/common/qsort.c
+++ b/common/qsort.c
@@ -59,8 +59,9 @@ typedef struct
#define CHAR_BIT 8
#endif
#define STACK_SIZE (CHAR_BIT * sizeof(size_t))
-#define PUSH(low, high) ((void) ((stack[i].lo = (low)), (stack[i].hi = (high)), i++))
-#define POP(low, high) ((void) (i--, (low = stack[i].lo), (high = stack[i].hi)))
+#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
+#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
+#define STACK_NOT_EMPTY (stack < top)
/* Order size using quicksort. This implementation incorporates
@@ -103,11 +104,11 @@ void ldb_qsort (void *const pbase, size_t total_elems, size_t size,
char *lo = base_ptr;
char *hi = &lo[size * (total_elems - 1)];
stack_node stack[STACK_SIZE];
- size_t i = 0;
+ stack_node *top = stack;
PUSH (NULL, NULL);
- do
+ while (STACK_NOT_EMPTY)
{
char *left_ptr;
char *right_ptr;
@@ -193,7 +194,6 @@ void ldb_qsort (void *const pbase, size_t total_elems, size_t size,
hi = right_ptr;
}
}
- while (i > 0 && i < STACK_SIZE);
}
/* Once the BASE_PTR array is partially sorted by quicksort the rest
diff --git a/ldb_ldb/ldb_ldb.c b/ldb_ldb/ldb_ldb.c
deleted file mode 100644
index a5a3612..0000000
--- a/ldb_ldb/ldb_ldb.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * ldb connection and module initialisation
- *
- * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-#include "ldb_private.h"
-#include "../ldb_tdb/ldb_tdb.h"
-#ifdef HAVE_LMDB
-#include "../ldb_mdb/ldb_mdb.h"
-#endif /* HAVE_LMDB */
-
-/*
- connect to the database
-*/
-static int lldb_connect(struct ldb_context *ldb,
- const char *url,
- unsigned int flags,
- const char *options[],
- struct ldb_module **module)
-{
- const char *path;
- int ret;
-
- /*
- * Check and remove the url prefix
- */
- if (strchr(url, ':')) {
- if (strncmp(url, "ldb://", 6) != 0) {
- ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Invalid ldb URL '%s'", url);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- path = url+6;
- } else {
- path = url;
- }
-
- /*
- * Don't create the database if it's not there
- */
- flags |= LDB_FLG_DONT_CREATE_DB;
-#ifdef HAVE_LMDB
- /*
- * Try opening the database as an lmdb
- */
- ret = lmdb_connect(ldb, path, flags, options, module);
- if (ret == LDB_SUCCESS) {
- return ret;
- }
- if (ret != LDB_ERR_UNAVAILABLE) {
- return ret;
- }
-
- /*
- * Not mdb so try as tdb
- */
-#endif /* HAVE_LMDB */
- ret = ltdb_connect(ldb, path, flags, options, module);
- return ret;
-}
-
-int ldb_ldb_init(const char *version)
-{
- LDB_MODULE_CHECK_VERSION(version);
- return ldb_register_backend("ldb", lldb_connect, false);
-}
diff --git a/ldb_map/ldb_map.c b/ldb_map/ldb_map.c
index b453dff..f2a86fe 100644
--- a/ldb_map/ldb_map.c
+++ b/ldb_map/ldb_map.c
@@ -523,8 +523,7 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct
"used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
}
-
- FALL_THROUGH;
+ /* fall through */
case LDB_MAP_KEEP:
case LDB_MAP_RENAME:
case LDB_MAP_RENDROP:
@@ -600,8 +599,7 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struc
"used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
}
-
- FALL_THROUGH;
+ /* fall through */
case LDB_MAP_KEEP:
case LDB_MAP_RENAME:
case LDB_MAP_RENDROP:
diff --git a/ldb_map/ldb_map_inbound.c b/ldb_map/ldb_map_inbound.c
index 861c4c1..461e681 100644
--- a/ldb_map/ldb_map_inbound.c
+++ b/ldb_map/ldb_map_inbound.c
@@ -87,8 +87,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, enum ldb_request_type
el = ldb_msg_el_map_local(module, remote, map, old);
break;
}
-
- FALL_THROUGH;
+ /* fall through */
case LDB_MAP_IGNORE:
goto local;
@@ -100,8 +99,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, enum ldb_request_type
map->local_name);
goto local;
}
-
- FALL_THROUGH;
+ /* fall through */
case LDB_MAP_KEEP:
case LDB_MAP_RENAME:
el = ldb_msg_el_map_local(module, remote, map, old);
diff --git a/ldb_map/ldb_map_outbound.c b/ldb_map/ldb_map_outbound.c
index 1f1a7e8..fd25c36 100644
--- a/ldb_map/ldb_map_outbound.c
+++ b/ldb_map/ldb_map_outbound.c
@@ -330,8 +330,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
attr_name);
return LDB_SUCCESS;
}
-
- FALL_THROUGH;
+ /* fall through */
case LDB_MAP_KEEP:
case LDB_MAP_RENAME:
case LDB_MAP_RENDROP:
diff --git a/ldb_mdb/ldb_mdb.c b/ldb_mdb/ldb_mdb.c
deleted file mode 100644
index af552fe..0000000
--- a/ldb_mdb/ldb_mdb.c
+++ /dev/null
@@ -1,887 +0,0 @@
-/*
- ldb database library using mdb back end
-
- Copyright (C) Jakub Hrozek 2014
- Copyright (C) Catalyst.Net Ltd 2017
-
- ** NOTE! The following LGPL license applies to the ldb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "ldb_mdb.h"
-#include "../ldb_tdb/ldb_tdb.h"
-#include "include/dlinklist.h"
-
-#define MDB_URL_PREFIX "mdb://"
-#define MDB_URL_PREFIX_SIZE (sizeof(MDB_URL_PREFIX)-1)
-
-#define LDB_MDB_MAX_KEY_LENGTH 511
-
-#define GIGABYTE (1024*1024*1024)
-
-int ldb_mdb_err_map(int lmdb_err)
-{
- switch (lmdb_err) {
- case MDB_SUCCESS:
- return LDB_SUCCESS;
- case EIO:
- return LDB_ERR_OPERATIONS_ERROR;
- case EBADE:
- case MDB_INCOMPATIBLE:
- case MDB_CORRUPTED:
- case MDB_INVALID:
- return LDB_ERR_UNAVAILABLE;
- case MDB_BAD_TXN:
- case MDB_BAD_VALSIZE:
-#ifdef MDB_BAD_DBI
- case MDB_BAD_DBI:
-#endif
- case MDB_PANIC:
- case EINVAL:
- return LDB_ERR_PROTOCOL_ERROR;
- case MDB_MAP_FULL:
- case MDB_DBS_FULL:
- case MDB_READERS_FULL:
- case MDB_TLS_FULL:
- case MDB_TXN_FULL:
- case EAGAIN:
- return LDB_ERR_BUSY;
- case MDB_KEYEXIST:
- return LDB_ERR_ENTRY_ALREADY_EXISTS;
- case MDB_NOTFOUND:
- case ENOENT:
- return LDB_ERR_NO_SUCH_OBJECT;
- case EACCES:
- return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
- default:
- break;
- }
- return LDB_ERR_OTHER;
-}
-
-#define ldb_mdb_error(ldb, ecode) lmdb_error_at(ldb, ecode, __FILE__, __LINE__)
-static int lmdb_error_at(struct ldb_context *ldb,
- int ecode,
- const char *file,
- int line)
-{
- int ldb_err = ldb_mdb_err_map(ecode);
- char *reason = mdb_strerror(ecode);
- ldb_asprintf_errstring(ldb,
- "(%d) - %s at %s:%d",
- ecode,
- reason,
- file,
- line);
- return ldb_err;
-}
-
-
-static bool lmdb_transaction_active(struct ltdb_private *ltdb)
-{
- return ltdb->lmdb_private->txlist != NULL;
-}
-
-static MDB_txn *lmdb_trans_get_tx(struct lmdb_trans *ltx)
-{
- if (ltx == NULL) {
- return NULL;
- }
-
- return ltx->tx;
-}
-
-static void trans_push(struct lmdb_private *lmdb, struct lmdb_trans *ltx)
-{
- if (lmdb->txlist) {
- talloc_steal(lmdb->txlist, ltx);
- }
-
- DLIST_ADD(lmdb->txlist, ltx);
-}
-
-static void trans_finished(struct lmdb_private *lmdb, struct lmdb_trans *ltx)
-{
- DLIST_REMOVE(lmdb->txlist, ltx);
- talloc_free(ltx);
-}
-
-
-static struct lmdb_trans *lmdb_private_trans_head(struct lmdb_private *lmdb)
-{
- struct lmdb_trans *ltx;
-
- ltx = lmdb->txlist;
- return ltx;
-}
-
-
-static MDB_txn *get_current_txn(struct lmdb_private *lmdb)
-{
- MDB_txn *txn = NULL;
-
- txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb));
- if (txn != NULL) {
- return txn;
- }
- if (lmdb->read_txn != NULL) {
- return lmdb->read_txn;
- }
- lmdb->error = MDB_BAD_TXN;
- ldb_set_errstring(lmdb->ldb, __location__":No active transaction\n");
- return NULL;
-}
-
-static int lmdb_store(struct ltdb_private *ltdb,
- struct ldb_val key,
- struct ldb_val data, int flags)
-{
- struct lmdb_private *lmdb = ltdb->lmdb_private;
- MDB_val mdb_key;
- MDB_val mdb_data;
- int mdb_flags;
- MDB_txn *txn = NULL;
- MDB_dbi dbi = 0;
-
- if (ltdb->read_only) {
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
-
- txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb));
- if (txn == NULL) {
- ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction");
- lmdb->error = MDB_PANIC;
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
- if (lmdb->error != MDB_SUCCESS) {
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- mdb_key.mv_size = key.length;
- mdb_key.mv_data = key.data;
-
- mdb_data.mv_size = data.length;
- mdb_data.mv_data = data.data;
-
- if (flags == TDB_INSERT) {
- mdb_flags = MDB_NOOVERWRITE;
- } else if ((flags == TDB_MODIFY)) {
- /*
- * Modifying a record, ensure that it exists.
- * This mimics the TDB semantics
- */
- MDB_val value;
- lmdb->error = mdb_get(txn, dbi, &mdb_key, &value);
- if (lmdb->error != MDB_SUCCESS) {
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
- mdb_flags = 0;
- } else {
- mdb_flags = 0;
- }
-
- lmdb->error = mdb_put(txn, dbi, &mdb_key, &mdb_data, mdb_flags);
- if (lmdb->error != MDB_SUCCESS) {
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- return ldb_mdb_err_map(lmdb->error);
-}
-
-static int lmdb_delete(struct ltdb_private *ltdb, struct ldb_val key)
-{
- struct lmdb_private *lmdb = ltdb->lmdb_private;
- MDB_val mdb_key;
- MDB_txn *txn = NULL;
- MDB_dbi dbi = 0;
-
- if (ltdb->read_only) {
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
-
- txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb));
- if (txn == NULL) {
- ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction");
- lmdb->error = MDB_PANIC;
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
- if (lmdb->error != MDB_SUCCESS) {
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- mdb_key.mv_size = key.length;
- mdb_key.mv_data = key.data;
-
- lmdb->error = mdb_del(txn, dbi, &mdb_key, NULL);
- if (lmdb->error != MDB_SUCCESS) {
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
- return ldb_mdb_err_map(lmdb->error);
-}
-
-static int lmdb_traverse_fn(struct ltdb_private *ltdb,
- ldb_kv_traverse_fn fn,
- void *ctx)
-{
- struct lmdb_private *lmdb = ltdb->lmdb_private;
- MDB_val mdb_key;
- MDB_val mdb_data;
- MDB_txn *txn = NULL;
- MDB_dbi dbi = 0;
- MDB_cursor *cursor = NULL;
- int ret;
-
- txn = get_current_txn(lmdb);
- if (txn == NULL) {
- ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction");
- lmdb->error = MDB_PANIC;
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
- if (lmdb->error != MDB_SUCCESS) {
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- lmdb->error = mdb_cursor_open(txn, dbi, &cursor);
- if (lmdb->error != MDB_SUCCESS) {
- goto done;
- }
-
- while ((lmdb->error = mdb_cursor_get(
- cursor, &mdb_key,
- &mdb_data, MDB_NEXT)) == MDB_SUCCESS) {
-
- struct ldb_val key = {
- .length = mdb_key.mv_size,
- .data = mdb_key.mv_data,
- };
- struct ldb_val data = {
- .length = mdb_data.mv_size,
- .data = mdb_data.mv_data,
- };
-
- ret = fn(ltdb, key, data, ctx);
- if (ret != 0) {
- goto done;
- }
- }
- if (lmdb->error == MDB_NOTFOUND) {
- lmdb->error = MDB_SUCCESS;
- }
-done:
- if (cursor != NULL) {
- mdb_cursor_close(cursor);
- }
-
- if (lmdb->error != MDB_SUCCESS) {
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
- return ldb_mdb_err_map(lmdb->error);
-}
-
-static int lmdb_update_in_iterate(struct ltdb_private *ltdb,
- struct ldb_val key,
- struct ldb_val key2,
- struct ldb_val data,
- void *state)
-{
- struct lmdb_private *lmdb = ltdb->lmdb_private;
- struct ldb_val copy;
- int ret = LDB_SUCCESS;
-
- /*
- * Need to take a copy of the data as the delete operation alters the
- * data, as it is in private lmdb memory.
- */
- copy.length = data.length;
- copy.data = talloc_memdup(ltdb, data.data, data.length);
- if (copy.data == NULL) {
- lmdb->error = MDB_PANIC;
- return ldb_oom(lmdb->ldb);
- }
-
- lmdb->error = lmdb_delete(ltdb, key);
- if (lmdb->error != MDB_SUCCESS) {
- ldb_debug(
- lmdb->ldb,
- LDB_DEBUG_ERROR,
- "Failed to delete %*.*s "
- "for rekey as %*.*s: %s",
- (int)key.length, (int)key.length,
- (const char *)key.data,
- (int)key2.length, (int)key2.length,
- (const char *)key.data,
- mdb_strerror(lmdb->error));
- ret = ldb_mdb_error(lmdb->ldb, lmdb->error);
- goto done;
- }
-
- lmdb->error = lmdb_store(ltdb, key2, copy, 0);
- if (lmdb->error != MDB_SUCCESS) {
- ldb_debug(
- lmdb->ldb,
- LDB_DEBUG_ERROR,
- "Failed to rekey %*.*s as %*.*s: %s",
- (int)key.length, (int)key.length,
- (const char *)key.data,
- (int)key2.length, (int)key2.length,
- (const char *)key.data,
- mdb_strerror(lmdb->error));
- ret = ldb_mdb_error(lmdb->ldb, lmdb->error);
- goto done;
- }
-
-done:
- if (copy.data != NULL) {
- TALLOC_FREE(copy.data);
- copy.length = 0;
- }
-
- /*
- * Explicity invalidate the data, as the delete has done this
- */
- data.length = 0;
- data.data = NULL;
-
- return ret;
-}
-
-/* Handles only a single record */
-static int lmdb_parse_record(struct ltdb_private *ltdb, struct ldb_val key,
- int (*parser)(struct ldb_val key, struct ldb_val data,
- void *private_data),
- void *ctx)
-{
- struct lmdb_private *lmdb = ltdb->lmdb_private;
- MDB_val mdb_key;
- MDB_val mdb_data;
- MDB_txn *txn = NULL;
- MDB_dbi dbi;
- struct ldb_val data;
-
- txn = get_current_txn(lmdb);
- if (txn == NULL) {
- ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction active");
- lmdb->error = MDB_PANIC;
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
- if (lmdb->error != MDB_SUCCESS) {
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- mdb_key.mv_size = key.length;
- mdb_key.mv_data = key.data;
-
- lmdb->error = mdb_get(txn, dbi, &mdb_key, &mdb_data);
- if (lmdb->error != MDB_SUCCESS) {
- /* TODO closing a handle should not even be necessary */
- mdb_dbi_close(lmdb->env, dbi);
- if (lmdb->error == MDB_NOTFOUND) {
- return LDB_ERR_NO_SUCH_OBJECT;
- }
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
- data.data = mdb_data.mv_data;
- data.length = mdb_data.mv_size;
-
- /* TODO closing a handle should not even be necessary */
- mdb_dbi_close(lmdb->env, dbi);
-
- return parser(key, data, ctx);
-}
-
-
-static int lmdb_lock_read(struct ldb_module *module)
-{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- struct lmdb_private *lmdb = ltdb->lmdb_private;
- pid_t pid = getpid();
-
- if (pid != lmdb->pid) {
- ldb_asprintf_errstring(
- lmdb->ldb,
- __location__": Reusing ldb opened by pid %d in "
- "process %d\n",
- lmdb->pid,
- pid);
- lmdb->error = MDB_BAD_TXN;
- return LDB_ERR_PROTOCOL_ERROR;
- }
-
- lmdb->error = MDB_SUCCESS;
- if (lmdb_transaction_active(ltdb) == false &&
- ltdb->read_lock_count == 0) {
- lmdb->error = mdb_txn_begin(lmdb->env,
- NULL,
- MDB_RDONLY,
- &lmdb->read_txn);
- }
- if (lmdb->error != MDB_SUCCESS) {
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- ltdb->read_lock_count++;
- return ldb_mdb_err_map(lmdb->error);
-}
-
-static int lmdb_unlock_read(struct ldb_module *module)
-{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
-
- if (lmdb_transaction_active(ltdb) == false && ltdb->read_lock_count == 1) {
- struct lmdb_private *lmdb = ltdb->lmdb_private;
- mdb_txn_commit(lmdb->read_txn);
- lmdb->read_txn = NULL;
- ltdb->read_lock_count--;
- return LDB_SUCCESS;
- }
- ltdb->read_lock_count--;
- return LDB_SUCCESS;
-}
-
-static int lmdb_transaction_start(struct ltdb_private *ltdb)
-{
- struct lmdb_private *lmdb = ltdb->lmdb_private;
- struct lmdb_trans *ltx;
- struct lmdb_trans *ltx_head;
- MDB_txn *tx_parent;
- pid_t pid = getpid();
-
- /* Do not take out the transaction lock on a read-only DB */
- if (ltdb->read_only) {
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
-
- ltx = talloc_zero(lmdb, struct lmdb_trans);
- if (ltx == NULL) {
- return ldb_oom(lmdb->ldb);
- }
-
- if (pid != lmdb->pid) {
- ldb_asprintf_errstring(
- lmdb->ldb,
- __location__": Reusing ldb opened by pid %d in "
- "process %d\n",
- lmdb->pid,
- pid);
- lmdb->error = MDB_BAD_TXN;
- return LDB_ERR_PROTOCOL_ERROR;
- }
-
- ltx_head = lmdb_private_trans_head(lmdb);
-
- tx_parent = lmdb_trans_get_tx(ltx_head);
-
- lmdb->error = mdb_txn_begin(lmdb->env, tx_parent, 0, &ltx->tx);
- if (lmdb->error != MDB_SUCCESS) {
- return ldb_mdb_error(lmdb->ldb, lmdb->error);
- }
-
- trans_push(lmdb, ltx);
-
- return ldb_mdb_err_map(lmdb->error);
-}
-
-static int lmdb_transaction_cancel(struct ltdb_private *ltdb)
-{
- struct lmdb_trans *ltx;
- struct lmdb_private *lmdb = ltdb->lmdb_private;
-
- ltx = lmdb_private_trans_head(lmdb);
- if (ltx == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- mdb_txn_abort(ltx->tx);
- trans_finished(lmdb, ltx);
- return LDB_SUCCESS;
-}
-
-static int lmdb_transaction_prepare_commit(struct ltdb_private *ltdb)
-{
- /* No need to prepare a commit */
- return LDB_SUCCESS;
-}
-
-static int lmdb_transaction_commit(struct ltdb_private *ltdb)
-{
- struct lmdb_trans *ltx;
- struct lmdb_private *lmdb = ltdb->lmdb_private;
-
- ltx = lmdb_private_trans_head(lmdb);
- if (ltx == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- lmdb->error = mdb_txn_commit(ltx->tx);
- trans_finished(lmdb, ltx);
-
- return lmdb->error;
-}
-
-static int lmdb_error(struct ltdb_private *ltdb)
-{
- return ldb_mdb_err_map(ltdb->lmdb_private->error);
-}
-
-static const char *lmdb_errorstr(struct ltdb_private *ltdb)
-{
- return mdb_strerror(ltdb->lmdb_private->error);
-}
-
-static const char * lmdb_name(struct ltdb_private *ltdb)
-{
- return "lmdb";
-}
-
-static bool lmdb_changed(struct ltdb_private *ltdb)
-{
- /*
- * lmdb does no provide a quick way to determine if the database
- * has changed. This function always returns true.
- *
- * Note that tdb uses a sequence number that allows this function
- * to be implemented efficiently.
- */
- return true;
-}
-
-static struct kv_db_ops lmdb_key_value_ops = {
- .store = lmdb_store,
- .delete = lmdb_delete,
- .iterate = lmdb_traverse_fn,
- .update_in_iterate = lmdb_update_in_iterate,
- .fetch_and_parse = lmdb_parse_record,
- .lock_read = lmdb_lock_read,
- .unlock_read = lmdb_unlock_read,
- .begin_write = lmdb_transaction_start,
- .prepare_write = lmdb_transaction_prepare_commit,
- .finish_write = lmdb_transaction_commit,
- .abort_write = lmdb_transaction_cancel,
- .error = lmdb_error,
- .errorstr = lmdb_errorstr,
- .name = lmdb_name,
- .has_changed = lmdb_changed,
- .transaction_active = lmdb_transaction_active,
-};
-
-static const char *lmdb_get_path(const char *url)
-{
- const char *path;
-
- /* parse the url */
- if (strchr(url, ':')) {
- if (strncmp(url, MDB_URL_PREFIX, MDB_URL_PREFIX_SIZE) != 0) {
- return NULL;
- }
- path = url + MDB_URL_PREFIX_SIZE;
- } else {
- path = url;
- }
-
- return path;
-}
-
-static int lmdb_pvt_destructor(struct lmdb_private *lmdb)
-{
- struct lmdb_trans *ltx = NULL;
-
- /* Check if this is a forked child */
- if (getpid() != lmdb->pid) {
- int fd = 0;
- /*
- * We cannot call mdb_env_close or commit any transactions,
- * otherwise they might appear finished in the parent.
- *
- */
-
- if (mdb_env_get_fd(lmdb->env, &fd) == 0) {
- close(fd);
- }
-
- /* Remove the pointer, so that no access should occur */
- lmdb->env = NULL;
-
- return 0;
- }
-
- /*
- * Close the read transaction if it's open
- */
- if (lmdb->read_txn != NULL) {
- mdb_txn_abort(lmdb->read_txn);
- }
-
- if (lmdb->env == NULL) {
- return 0;
- }
-
- /*
- * Abort any currently active transactions
- */
- ltx = lmdb_private_trans_head(lmdb);
- while (ltx != NULL) {
- mdb_txn_abort(ltx->tx);
- trans_finished(lmdb, ltx);
- ltx = lmdb_private_trans_head(lmdb);
- }
- lmdb->env = NULL;
-
- return 0;
-}
-
-struct mdb_env_wrap {
- struct mdb_env_wrap *next, *prev;
- dev_t device;
- ino_t inode;
- MDB_env *env;
- pid_t pid;
-};
-
-static struct mdb_env_wrap *mdb_list;
-
-/* destroy the last connection to an mdb */
-static int mdb_env_wrap_destructor(struct mdb_env_wrap *w)
-{
- mdb_env_close(w->env);
- DLIST_REMOVE(mdb_list, w);
- return 0;
-}
-
-static int lmdb_open_env(TALLOC_CTX *mem_ctx,
- MDB_env **env,
- struct ldb_context *ldb,
- const char *path,
- unsigned int flags)
-{
- int ret;
- const size_t mmap_size = 8LL * GIGABYTE;
- unsigned int mdb_flags = MDB_NOSUBDIR|MDB_NOTLS;
- /*
- * MDB_NOSUBDIR implies there is a separate file called path and a
- * separate lockfile called path-lock
- */
-
- struct mdb_env_wrap *w;
- struct stat st;
- pid_t pid = getpid();
- int fd = 0;
- unsigned v;
-
- if (stat(path, &st) == 0) {
- for (w=mdb_list;w;w=w->next) {
- if (st.st_dev == w->device &&
- st.st_ino == w->inode &&
- pid == w->pid) {
- /*
- * We must have only one MDB_env per process
- */
- if (!talloc_reference(mem_ctx, w)) {
- return ldb_oom(ldb);
- }
- *env = w->env;
- return LDB_SUCCESS;
- }
- }
- }
-
- w = talloc(mem_ctx, struct mdb_env_wrap);
- if (w == NULL) {
- return ldb_oom(ldb);
- }
-
- ret = mdb_env_create(env);
- if (ret != 0) {
- ldb_asprintf_errstring(
- ldb,
- "Could not create MDB environment %s: %s\n",
- path,
- mdb_strerror(ret));
- return ldb_mdb_err_map(ret);
- }
-
- /*
- * Currently we set a 8Gb maximum database size
- * via the constant mmap_size above
- */
- ret = mdb_env_set_mapsize(*env, mmap_size);
- if (ret != 0) {
- ldb_asprintf_errstring(
- ldb,
- "Could not set MDB mmap() size to %llu on %s: %s\n",
- (unsigned long long)(mmap_size),
- path,
- mdb_strerror(ret));
- TALLOC_FREE(w);
- return ldb_mdb_err_map(ret);
- }
-
- mdb_env_set_maxreaders(*env, 100000);
- /*
- * As we ensure that there is only one MDB_env open per database per
- * process. We can not use the MDB_RDONLY flag, as another ldb may be
- * opened in read write mode
- */
- if (flags & LDB_FLG_NOSYNC) {
- mdb_flags |= MDB_NOSYNC;
- }
- ret = mdb_env_open(*env, path, mdb_flags, 0644);
- if (ret != 0) {
- ldb_asprintf_errstring(ldb,
- "Could not open DB %s: %s\n",
- path, mdb_strerror(ret));
- TALLOC_FREE(w);
- return ldb_mdb_err_map(ret);
- }
-
- ret = mdb_env_get_fd(*env, &fd);
- if (ret != 0) {
- ldb_asprintf_errstring(ldb,
- "Could not obtain DB FD %s: %s\n",
- path, mdb_strerror(ret));
- TALLOC_FREE(w);
- return ldb_mdb_err_map(ret);
- }
-
- /* Just as for TDB: on exec, don't inherit the fd */
- v = fcntl(fd, F_GETFD, 0);
- fcntl(fd, F_SETFD, v | FD_CLOEXEC);
-
- if (fstat(fd, &st) != 0) {
- ldb_asprintf_errstring(
- ldb,
- "Could not stat %s:\n",
- path);
- TALLOC_FREE(w);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- w->env = *env;
- w->device = st.st_dev;
- w->inode = st.st_ino;
- w->pid = pid;
-
- talloc_set_destructor(w, mdb_env_wrap_destructor);
-
- DLIST_ADD(mdb_list, w);
-
- return LDB_SUCCESS;
-
-}
-
-static int lmdb_pvt_open(struct lmdb_private *lmdb,
- struct ldb_context *ldb,
- const char *path,
- unsigned int flags)
-{
- int ret;
- int lmdb_max_key_length;
-
- if (flags & LDB_FLG_DONT_CREATE_DB) {
- struct stat st;
- if (stat(path, &st) != 0) {
- return LDB_ERR_UNAVAILABLE;
- }
- }
-
- ret = lmdb_open_env(lmdb, &lmdb->env, ldb, path, flags);
- if (ret != 0) {
- return ret;
- }
-
- /* Close when lmdb is released */
- talloc_set_destructor(lmdb, lmdb_pvt_destructor);
-
- /* Store the original pid during the LMDB open */
- lmdb->pid = getpid();
-
- lmdb_max_key_length = mdb_env_get_maxkeysize(lmdb->env);
-
- /* This will never happen, but if it does make sure to freak out */
- if (lmdb_max_key_length < LDB_MDB_MAX_KEY_LENGTH) {
- return ldb_operr(ldb);
- }
-
- return LDB_SUCCESS;
-}
-
-int lmdb_connect(struct ldb_context *ldb,
- const char *url,
- unsigned int flags,
- const char *options[],
- struct ldb_module **_module)
-{
- const char *path = NULL;
- struct lmdb_private *lmdb = NULL;
- struct ltdb_private *ltdb = NULL;
- int ret;
-
- /*
- * We hold locks, so we must use a private event context
- * on each returned handle
- */
- ldb_set_require_private_event_context(ldb);
-
- path = lmdb_get_path(url);
- if (path == NULL) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid mdb URL '%s'", url);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ltdb = talloc_zero(ldb, struct ltdb_private);
- if (!ltdb) {
- ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- lmdb = talloc_zero(ltdb, struct lmdb_private);
- if (lmdb == NULL) {
- TALLOC_FREE(ltdb);
- return ldb_oom(ldb);
- }
- lmdb->ldb = ldb;
- ltdb->kv_ops = &lmdb_key_value_ops;
-
- ret = lmdb_pvt_open(lmdb, ldb, path, flags);
- if (ret != LDB_SUCCESS) {
- TALLOC_FREE(ltdb);
- return ret;
- }
-
- ltdb->lmdb_private = lmdb;
- if (flags & LDB_FLG_RDONLY) {
- ltdb->read_only = true;
- }
-
- /*
- * This maximum length becomes encoded in the index values so
- * must never change even if LMDB starts to allow longer keys.
- * The override option is max_key_len_for_self_test, and is
- * used for testing only.
- */
- ltdb->max_key_length = LDB_MDB_MAX_KEY_LENGTH;
-
- return init_store(ltdb, "ldb_mdb backend", ldb, options, _module);
-}
diff --git a/ldb_mdb/ldb_mdb.h b/ldb_mdb/ldb_mdb.h
deleted file mode 100644
index 8f21493..0000000
--- a/ldb_mdb/ldb_mdb.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- ldb database library using mdb back end - transaction operations
-
- Copyright (C) Jakub Hrozek 2015
- Copyright (C) Catalyst.Net Ltd 2017
-
- ** NOTE! The following LGPL license applies to the ldb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _LDB_MDB_H_
-#define _LDB_MDB_H_
-
-#include "ldb_private.h"
-#include <lmdb.h>
-
-struct lmdb_private {
- struct ldb_context *ldb;
- MDB_env *env;
-
- struct lmdb_trans *txlist;
-
- struct ldb_mdb_metadata {
- struct ldb_message *attributes;
- unsigned seqnum;
- } *meta;
- int error;
- MDB_txn *read_txn;
-
- pid_t pid;
-
-};
-
-struct lmdb_trans {
- struct lmdb_trans *next;
- struct lmdb_trans *prev;
-
- MDB_txn *tx;
-};
-
-int ldb_mdb_err_map(int lmdb_err);
-int lmdb_connect(struct ldb_context *ldb, const char *url,
- unsigned int flags, const char *options[],
- struct ldb_module **_module);
-
-#endif /* _LDB_MDB_H_ */
diff --git a/ldb_mdb/ldb_mdb_init.c b/ldb_mdb/ldb_mdb_init.c
deleted file mode 100644
index 339c3f2..0000000
--- a/ldb_mdb/ldb_mdb_init.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- ldb database library using mdb back end
-
- Copyright (C) Jakub Hrozek 2014
- Copyright (C) Catalyst.Net Ltd 2017
-
- ** NOTE! The following LGPL license applies to the ldb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "ldb_mdb.h"
-
-int ldb_mdb_init(const char *version)
-{
- LDB_MODULE_CHECK_VERSION(version);
- return ldb_register_backend("mdb", lmdb_connect, false);
-}
diff --git a/ldb_sqlite3/ldb_sqlite3.c b/ldb_sqlite3/ldb_sqlite3.c
index f94dc99..0f5abf8 100644
--- a/ldb_sqlite3/ldb_sqlite3.c
+++ b/ldb_sqlite3/ldb_sqlite3.c
@@ -323,6 +323,9 @@ static char *parsetree_to_sql(struct ldb_module *module,
const char *cdn = ldb_dn_get_casefold(
ldb_dn_new(mem_ctx, ldb,
(const char *)value.data));
+ if (cdn == NULL) {
+ return NULL;
+ }
return lsqlite3_tprintf(mem_ctx,
"SELECT eid FROM ldb_entry "
diff --git a/ldb_tdb/ldb_cache.c b/ldb_tdb/ldb_cache.c
index 1856fb1..5b90bd9 100644
--- a/ldb_tdb/ldb_cache.c
+++ b/ldb_tdb/ldb_cache.c
@@ -238,7 +238,7 @@ static int ltdb_index_load(struct ldb_module *module,
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
struct ldb_dn *indexlist_dn;
- int r, lmdb_subdb_version;
+ int r;
if (ldb->schema.index_handler_override) {
/*
@@ -291,20 +291,6 @@ static int ltdb_index_load(struct ldb_module *module,
= ldb_msg_find_attr_as_string(ltdb->cache->indexlist,
LTDB_IDX_DN_GUID, NULL);
- lmdb_subdb_version
- = ldb_msg_find_attr_as_int(ltdb->cache->indexlist,
- LTDB_IDX_LMDB_SUBDB, 0);
-
- if (lmdb_subdb_version != 0) {
- ldb_set_errstring(ldb,
- "FATAL: This ldb_mdb database has "
- "been written in a new verson of LDB "
- "using a sub-database index that "
- "is not understood by ldb "
- LDB_VERSION);
- return -1;
- }
-
return 0;
}
@@ -400,13 +386,13 @@ int ltdb_cache_load(struct ldb_module *module)
uint64_t seq;
struct ldb_message *baseinfo = NULL, *options = NULL;
const struct ldb_schema_attribute *a;
- bool have_write_txn = false;
int r;
ldb = ldb_module_get_ctx(module);
/* a very fast check to avoid extra database reads */
- if (ltdb->cache != NULL && !ltdb->kv_ops->has_changed(ltdb)) {
+ if (ltdb->cache != NULL &&
+ tdb_get_seqnum(ltdb->tdb) == ltdb->tdb_seqnum) {
return 0;
}
@@ -421,42 +407,30 @@ int ltdb_cache_load(struct ldb_module *module)
baseinfo_dn = ldb_dn_new(baseinfo, ldb, LTDB_BASEINFO);
if (baseinfo_dn == NULL) goto failed;
- r = ltdb->kv_ops->lock_read(module);
- if (r != LDB_SUCCESS) {
- goto failed;
- }
r= ltdb_search_dn1(module, baseinfo_dn, baseinfo, 0);
if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
- goto failed_and_unlock;
+ goto failed;
}
-
+
/* possibly initialise the baseinfo */
if (r == LDB_ERR_NO_SUCH_OBJECT) {
- /* Give up the read lock, try again with a write lock */
- r = ltdb->kv_ops->unlock_read(module);
- if (r != LDB_SUCCESS) {
+ if (tdb_transaction_start(ltdb->tdb) != 0) {
goto failed;
}
- if (ltdb->kv_ops->begin_write(ltdb) != 0) {
- goto failed;
- }
-
- have_write_txn = true;
-
/* error handling for ltdb_baseinfo_init() is by
looking for the record again. */
ltdb_baseinfo_init(module);
+ tdb_transaction_commit(ltdb->tdb);
+
if (ltdb_search_dn1(module, baseinfo_dn, baseinfo, 0) != LDB_SUCCESS) {
- goto failed_and_unlock;
+ goto failed;
}
-
}
- /* Ignore the result, and update the sequence number */
- ltdb->kv_ops->has_changed(ltdb);
+ ltdb->tdb_seqnum = tdb_get_seqnum(ltdb->tdb);
/* if the current internal sequence number is the same as the one
in the database then assume the rest of the cache is OK */
@@ -467,17 +441,16 @@ int ltdb_cache_load(struct ldb_module *module)
ltdb->sequence_number = seq;
/* Read an interpret database options */
-
options = ldb_msg_new(ltdb->cache);
- if (options == NULL) goto failed_and_unlock;
+ if (options == NULL) goto failed;
options_dn = ldb_dn_new(options, ldb, LTDB_OPTIONS);
- if (options_dn == NULL) goto failed_and_unlock;
+ if (options_dn == NULL) goto failed;
r= ltdb_search_dn1(module, options_dn, options, 0);
talloc_free(options_dn);
if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
- goto failed_and_unlock;
+ goto failed;
}
/* set flags if they do exist */
@@ -504,7 +477,7 @@ int ltdb_cache_load(struct ldb_module *module)
ltdb_attributes_unload(module);
if (ltdb_index_load(module, ltdb) == -1) {
- goto failed_and_unlock;
+ goto failed;
}
/*
@@ -513,7 +486,7 @@ int ltdb_cache_load(struct ldb_module *module)
* partition module.
*/
if (ltdb_attributes_load(module) == -1) {
- goto failed_and_unlock;
+ goto failed;
}
ltdb->GUID_index_syntax = NULL;
@@ -528,25 +501,10 @@ int ltdb_cache_load(struct ldb_module *module)
}
done:
- if (have_write_txn) {
- if (ltdb->kv_ops->finish_write(ltdb) != 0) {
- goto failed;
- }
- } else {
- ltdb->kv_ops->unlock_read(module);
- }
-
talloc_free(options);
talloc_free(baseinfo);
return 0;
-failed_and_unlock:
- if (have_write_txn) {
- ltdb->kv_ops->abort_write(ltdb);
- } else {
- ltdb->kv_ops->unlock_read(module);
- }
-
failed:
talloc_free(options);
talloc_free(baseinfo);
@@ -634,7 +592,7 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
/* updating the tdb_seqnum here avoids us reloading the cache
records due to our own modification */
- ltdb->kv_ops->has_changed(ltdb);
+ ltdb->tdb_seqnum = tdb_get_seqnum(ltdb->tdb);
return ret;
}
diff --git a/ldb_tdb/ldb_index.c b/ldb_tdb/ldb_index.c
index 7bd843e..429c8f5 100644
--- a/ldb_tdb/ldb_index.c
+++ b/ldb_tdb/ldb_index.c
@@ -165,19 +165,13 @@ struct ltdb_idxptr {
int error;
};
-enum key_truncation {
- KEY_NOT_TRUNCATED,
- KEY_TRUNCATED,
-};
-
static int ltdb_write_index_dn_guid(struct ldb_module *module,
const struct ldb_message *msg,
int add);
static int ltdb_index_dn_base_dn(struct ldb_module *module,
struct ltdb_private *ltdb,
struct ldb_dn *base_dn,
- struct dn_list *dn_list,
- enum key_truncation *truncation);
+ struct dn_list *dn_list);
static void ltdb_dn_list_sort(struct ltdb_private *ltdb,
struct dn_list *list);
@@ -189,13 +183,6 @@ static void ltdb_dn_list_sort(struct ltdb_private *ltdb,
#define LTDB_GUID_INDEXING_VERSION 3
-static unsigned ltdb_max_key_length(struct ltdb_private *ltdb) {
- if (ltdb->max_key_length == 0){
- return UINT_MAX;
- }
- return ltdb->max_key_length;
-}
-
/* enable the idxptr mode when transactions start */
int ltdb_index_transaction_start(struct ldb_module *module)
{
@@ -416,6 +403,7 @@ normal_index:
"expected %d for %s",
version, LTDB_INDEXING_VERSION,
ldb_dn_get_linearized(dn));
+ talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -433,19 +421,26 @@ normal_index:
"expected %d for %s",
version, LTDB_GUID_INDEXING_VERSION,
ldb_dn_get_linearized(dn));
+ talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
- if (el->num_values == 0) {
+ if (el->num_values != 1) {
+ talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
if ((el->values[0].length % LTDB_GUID_SIZE) != 0) {
+ talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
list->count = el->values[0].length / LTDB_GUID_SIZE;
list->dn = talloc_array(list, struct ldb_val, list->count);
+ if (list->dn == NULL) {
+ talloc_free(msg);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
/*
* The actual data is on msg, due to
@@ -472,16 +467,13 @@ int ltdb_key_dn_from_idx(struct ldb_module *module,
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
int ret;
- int index = 0;
- enum key_truncation truncation = KEY_NOT_TRUNCATED;
struct dn_list *list = talloc(mem_ctx, struct dn_list);
if (list == NULL) {
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
-
- ret = ltdb_index_dn_base_dn(module, ltdb, dn, list, &truncation);
+ ret = ltdb_index_dn_base_dn(module, ltdb, dn, list);
if (ret != LDB_SUCCESS) {
TALLOC_FREE(list);
return ret;
@@ -491,8 +483,7 @@ int ltdb_key_dn_from_idx(struct ldb_module *module,
TALLOC_FREE(list);
return LDB_ERR_NO_SUCH_OBJECT;
}
-
- if (list->count > 1 && truncation == KEY_NOT_TRUNCATED) {
+ if (list->count > 1) {
const char *dn_str = ldb_dn_get_linearized(dn);
ldb_asprintf_errstring(ldb_module_get_ctx(module),
__location__
@@ -505,81 +496,9 @@ int ltdb_key_dn_from_idx(struct ldb_module *module,
return LDB_ERR_CONSTRAINT_VIOLATION;
}
- if (list->count > 0 && truncation == KEY_TRUNCATED) {
- /*
- * DN key has been truncated, need to inspect the actual
- * records to locate the actual DN
- */
- int i;
- index = -1;
- for (i=0; i < list->count; i++) {
- uint8_t guid_key[LTDB_GUID_KEY_SIZE];
- TDB_DATA key = {
- .dptr = guid_key,
- .dsize = sizeof(guid_key)
- };
- const int flags = LDB_UNPACK_DATA_FLAG_NO_ATTRS;
- struct ldb_message *rec = ldb_msg_new(ldb);
- if (rec == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ret = ltdb_idx_to_key(module, ltdb,
- ldb, &list->dn[i],
- &key);
- if (ret != LDB_SUCCESS) {
- TALLOC_FREE(list);
- TALLOC_FREE(rec);
- return ret;
- }
-
- ret = ltdb_search_key(module, ltdb, key,
- rec, flags);
- if (key.dptr != guid_key) {
- TALLOC_FREE(key.dptr);
- }
- if (ret == LDB_ERR_NO_SUCH_OBJECT) {
- /*
- * the record has disappeared?
- * yes, this can happen
- */
- TALLOC_FREE(rec);
- continue;
- }
-
- if (ret != LDB_SUCCESS) {
- /* an internal error */
- TALLOC_FREE(rec);
- TALLOC_FREE(list);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /*
- * We found the actual DN that we wanted from in the
- * multiple values that matched the index
- * (due to truncation), so return that.
- *
- */
- if (ldb_dn_compare(dn, rec->dn) == 0) {
- index = i;
- TALLOC_FREE(rec);
- break;
- }
- }
-
- /*
- * We matched the index but the actual DN we wanted
- * was not here.
- */
- if (index == -1) {
- TALLOC_FREE(list);
- return LDB_ERR_NO_SUCH_OBJECT;
- }
- }
-
/* The tdb_key memory is allocated by the caller */
ret = ltdb_guid_to_key(module, ltdb,
- &list->dn[index], tdb_key);
+ &list->dn[0], tdb_key);
TALLOC_FREE(list);
if (ret != LDB_SUCCESS) {
@@ -612,9 +531,9 @@ static int ltdb_dn_list_store_full(struct ldb_module *module,
if (list->count == 0) {
ret = ltdb_delete_noindex(module, msg);
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
- talloc_free(msg);
- return LDB_SUCCESS;
+ ret = LDB_SUCCESS;
}
+ talloc_free(msg);
return ret;
}
@@ -710,6 +629,9 @@ static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn,
}
key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn));
+ if (key.dptr == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
key.dsize = strlen((char *)key.dptr);
rec = tdb_fetch(ltdb->idxptr->itdb, key);
@@ -832,8 +754,7 @@ int ltdb_index_transaction_cancel(struct ldb_module *module)
static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
struct ltdb_private *ltdb,
const char *attr, const struct ldb_val *value,
- const struct ldb_schema_attribute **ap,
- enum key_truncation *truncation)
+ const struct ldb_schema_attribute **ap)
{
struct ldb_dn *ret;
struct ldb_val v;
@@ -843,17 +764,6 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
int r;
bool should_b64_encode;
- unsigned int max_key_length = ltdb_max_key_length(ltdb);
- size_t key_len = 0;
- size_t attr_len = 0;
- const size_t indx_len = sizeof(LTDB_INDEX) - 1;
- unsigned frmt_len = 0;
- const size_t additional_key_length = 4;
- unsigned int num_separators = 3; /* Estimate for overflow check */
- const size_t min_data = 1;
- const size_t min_key_length = additional_key_length
- + indx_len + num_separators + min_data;
-
if (attr[0] == '@') {
attr_for_dn = attr;
v = *value;
@@ -889,30 +799,6 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
return NULL;
}
}
- attr_len = strlen(attr_for_dn);
-
- /*
- * Check if there is any hope this will fit into the DB.
- * Overflow here is not actually critical the code below
- * checks again to make the printf and the DB does another
- * check for too long keys
- */
- if (max_key_length - attr_len < min_key_length) {
- ldb_asprintf_errstring(
- ldb,
- __location__ ": max_key_length "
- "is too small (%u) < (%u)",
- max_key_length,
- (unsigned)(min_key_length + attr_len));
- talloc_free(attr_folded);
- return NULL;
- }
-
- /*
- * ltdb_key_dn() makes something 4 bytes longer, it adds a leading
- * "DN=" and a trailing string terminator
- */
- max_key_length -= additional_key_length;
/*
* We do not base 64 encode a DN in a key, it has already been
@@ -937,70 +823,18 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
}
if (should_b64_encode) {
- size_t vstr_len = 0;
char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length);
if (!vstr) {
talloc_free(attr_folded);
return NULL;
}
- vstr_len = strlen(vstr);
- /*
- * Overflow here is not critical as we only use this
- * to choose the printf truncation
- */
- key_len = num_separators + indx_len + attr_len + vstr_len;
- if (key_len > max_key_length) {
- size_t excess = key_len - max_key_length;
- frmt_len = vstr_len - excess;
- *truncation = KEY_TRUNCATED;
- /*
- * Truncated keys are placed in a separate key space
- * from the non truncated keys
- * Note: the double hash "##" is not a typo and
- * indicates that the following value is base64 encoded
- */
- ret = ldb_dn_new_fmt(ldb, ldb, "%s#%s##%.*s",
- LTDB_INDEX, attr_for_dn,
- frmt_len, vstr);
- } else {
- frmt_len = vstr_len;
- *truncation = KEY_NOT_TRUNCATED;
- /*
- * Note: the double colon "::" is not a typo and
- * indicates that the following value is base64 encoded
- */
- ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%.*s",
- LTDB_INDEX, attr_for_dn,
- frmt_len, vstr);
- }
+ ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX,
+ attr_for_dn, vstr);
talloc_free(vstr);
} else {
- /* Only need two seperators */
- num_separators = 2;
-
- /*
- * Overflow here is not critical as we only use this
- * to choose the printf truncation
- */
- key_len = num_separators + indx_len + attr_len + (int)v.length;
- if (key_len > max_key_length) {
- size_t excess = key_len - max_key_length;
- frmt_len = v.length - excess;
- *truncation = KEY_TRUNCATED;
- /*
- * Truncated keys are placed in a separate key space
- * from the non truncated keys
- */
- ret = ldb_dn_new_fmt(ldb, ldb, "%s#%s#%.*s",
- LTDB_INDEX, attr_for_dn,
- frmt_len, (char *)v.data);
- } else {
- frmt_len = v.length;
- *truncation = KEY_NOT_TRUNCATED;
- ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s",
- LTDB_INDEX, attr_for_dn,
- frmt_len, (char *)v.data);
- }
+ ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s", LTDB_INDEX,
+ attr_for_dn,
+ (int)v.length, (char *)v.data);
}
if (v.data != value->data) {
@@ -1085,7 +919,6 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
struct ldb_context *ldb;
struct ldb_dn *dn;
int ret;
- enum key_truncation truncation = KEY_NOT_TRUNCATED;
ldb = ldb_module_get_ctx(module);
@@ -1102,12 +935,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
search criterion */
dn = ltdb_index_key(ldb, ltdb,
tree->u.equality.attr,
- &tree->u.equality.value, NULL, &truncation);
- /*
- * We ignore truncation here and allow multi-valued matches
- * as ltdb_search_indexed will filter out the wrong one in
- * ltdb_index_filter() which calls ldb_match_message().
- */
+ &tree->u.equality.value, NULL);
if (!dn) return LDB_ERR_OPERATIONS_ERROR;
ret = ltdb_dn_list_load(module, ltdb, dn, list);
@@ -1142,7 +970,7 @@ static int ltdb_index_dn_leaf(struct ldb_module *module,
return LDB_SUCCESS;
}
if (ldb_attr_dn(tree->u.equality.attr) == 0) {
- enum key_truncation truncation = KEY_NOT_TRUNCATED;
+ bool valid_dn = false;
struct ldb_dn *dn
= ldb_dn_from_ldb_val(list,
ldb_module_get_ctx(module),
@@ -1154,6 +982,14 @@ static int ltdb_index_dn_leaf(struct ldb_module *module,
return LDB_SUCCESS;
}
+ valid_dn = ldb_dn_validate(dn);
+ if (valid_dn == false) {
+ /* If we can't parse it, no match */
+ list->dn = NULL;
+ list->count = 0;
+ return LDB_SUCCESS;
+ }
+
/*
* Re-use the same code we use for a SCOPE_BASE
* search
@@ -1161,13 +997,7 @@ static int ltdb_index_dn_leaf(struct ldb_module *module,
* We can't call TALLOC_FREE(dn) as this must belong
* to list for the memory to remain valid.
*/
- return ltdb_index_dn_base_dn(module, ltdb, dn, list,
- &truncation);
- /*
- * We ignore truncation here and allow multi-valued matches
- * as ltdb_search_indexed will filter out the wrong one in
- * ltdb_index_filter() which calls ldb_match_message().
- */
+ return ltdb_index_dn_base_dn(module, ltdb, dn, list);
} else if ((ltdb->cache->GUID_index_attribute != NULL) &&
(ldb_attr_cmp(tree->u.equality.attr,
@@ -1573,8 +1403,7 @@ static int ltdb_index_dn_attr(struct ldb_module *module,
struct ltdb_private *ltdb,
const char *attr,
struct ldb_dn *dn,
- struct dn_list *list,
- enum key_truncation *truncation)
+ struct dn_list *list)
{
struct ldb_context *ldb;
struct ldb_dn *key;
@@ -1585,8 +1414,17 @@ static int ltdb_index_dn_attr(struct ldb_module *module,
/* work out the index key from the parent DN */
val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(dn));
+ if (val.data == NULL) {
+ const char *dn_str = ldb_dn_get_linearized(dn);
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ __location__
+ ": Failed to get casefold DN "
+ "from: %s",
+ dn_str);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
val.length = strlen((char *)val.data);
- key = ltdb_index_key(ldb, ltdb, attr, &val, NULL, truncation);
+ key = ltdb_index_key(ldb, ltdb, attr, &val, NULL);
if (!key) {
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
@@ -1611,14 +1449,12 @@ static int ltdb_index_dn_attr(struct ldb_module *module,
static int ltdb_index_dn_one(struct ldb_module *module,
struct ltdb_private *ltdb,
struct ldb_dn *parent_dn,
- struct dn_list *list,
- enum key_truncation *truncation)
+ struct dn_list *list)
{
/* Ensure we do not shortcut on intersection for this list */
list->strict = true;
return ltdb_index_dn_attr(module, ltdb,
- LTDB_IDXONE, parent_dn, list, truncation);
-
+ LTDB_IDXONE, parent_dn, list);
}
/*
@@ -1627,8 +1463,7 @@ static int ltdb_index_dn_one(struct ldb_module *module,
static int ltdb_index_dn_base_dn(struct ldb_module *module,
struct ltdb_private *ltdb,
struct ldb_dn *base_dn,
- struct dn_list *dn_list,
- enum key_truncation *truncation)
+ struct dn_list *dn_list)
{
const struct ldb_val *guid_val = NULL;
if (ltdb->cache->GUID_index_attribute == NULL) {
@@ -1665,7 +1500,7 @@ static int ltdb_index_dn_base_dn(struct ldb_module *module,
}
return ltdb_index_dn_attr(module, ltdb,
- LTDB_IDXDN, base_dn, dn_list, truncation);
+ LTDB_IDXDN, base_dn, dn_list);
}
/*
@@ -1717,8 +1552,7 @@ static int ltdb_index_dn(struct ldb_module *module,
static int ltdb_index_filter(struct ltdb_private *ltdb,
const struct dn_list *dn_list,
struct ltdb_context *ac,
- uint32_t *match_count,
- enum key_truncation scope_one_truncation)
+ uint32_t *match_count)
{
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
struct ldb_message *msg;
@@ -1753,13 +1587,14 @@ static int ltdb_index_filter(struct ltdb_private *ltdb,
struct guid_tdb_key,
dn_list->count);
+ if (key_values == NULL) {
+ talloc_free(keys);
+ return ldb_module_oom(ac->module);
+ }
for (i = 0; i < dn_list->count; i++) {
keys[i].dptr = key_values[i].guid_key;
keys[i].dsize = sizeof(key_values[i].guid_key);
}
- if (key_values == NULL) {
- return ldb_module_oom(ac->module);
- }
} else {
for (i = 0; i < dn_list->count; i++) {
keys[i].dptr = NULL;
@@ -1776,6 +1611,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb,
&dn_list->dn[i],
&keys[num_keys]);
if (ret != LDB_SUCCESS) {
+ talloc_free(keys);
return ret;
}
@@ -1813,6 +1649,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb,
bool matched;
msg = ldb_msg_new(ac);
if (!msg) {
+ talloc_free(keys);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -1833,19 +1670,15 @@ static int ltdb_index_filter(struct ltdb_private *ltdb,
if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
/* an internal error */
+ talloc_free(keys);
talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
- /*
- * We trust the index for LDB_SCOPE_ONELEVEL
- * unless the index key has been truncated.
- *
- * LDB_SCOPE_BASE is not passed in by our only caller.
- */
- if (ac->scope == LDB_SCOPE_ONELEVEL
- && ltdb->cache->one_level_indexes
- && scope_one_truncation == KEY_NOT_TRUNCATED) {
+ /* We trust the index for SCOPE_ONELEVEL and SCOPE_BASE */
+ if ((ac->scope == LDB_SCOPE_ONELEVEL
+ && ltdb->cache->one_level_indexes)
+ || ac->scope == LDB_SCOPE_BASE) {
ret = ldb_match_message(ldb, msg, ac->tree,
ac->scope, &matched);
} else {
@@ -1855,6 +1688,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb,
}
if (ret != LDB_SUCCESS) {
+ talloc_free(keys);
talloc_free(msg);
return ret;
}
@@ -1869,6 +1703,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb,
talloc_free(msg);
if (ret == -1) {
+ talloc_free(keys);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -1878,6 +1713,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb,
* is the callbacks responsiblity, and should
* not be talloc_free()'ed */
ac->request_terminated = true;
+ talloc_free(keys);
return ret;
}
@@ -1919,7 +1755,6 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
struct dn_list *dn_list;
int ret;
enum ldb_scope index_scope;
- enum key_truncation scope_one_truncation = KEY_NOT_TRUNCATED;
/* see if indexing is enabled */
if (!ltdb->cache->attribute_indexes &&
@@ -1949,10 +1784,17 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
switch (index_scope) {
case LDB_SCOPE_BASE:
/*
- * The only caller will have filtered the operation out
- * so we should never get here
+ * If we ever start to also load the index values for
+ * the tree, we must ensure we strictly intersect with
+ * this list, as we trust the BASE index
*/
- return ldb_operr(ldb);
+ ret = ltdb_index_dn_base_dn(ac->module, ltdb,
+ ac->base, dn_list);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(dn_list);
+ return ret;
+ }
+ break;
case LDB_SCOPE_ONELEVEL:
/*
@@ -1960,8 +1802,7 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
* the tree, we must ensure we strictly intersect with
* this list, as we trust the ONELEVEL index
*/
- ret = ltdb_index_dn_one(ac->module, ltdb, ac->base, dn_list,
- &scope_one_truncation);
+ ret = ltdb_index_dn_one(ac->module, ltdb, ac->base, dn_list);
if (ret != LDB_SUCCESS) {
talloc_free(dn_list);
return ret;
@@ -2031,19 +1872,7 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
break;
}
- /*
- * It is critical that this function do the re-filter even
- * on things found by the index as the index can over-match
- * in cases of truncation (as well as when it decides it is
- * not worth further filtering)
- *
- * If this changes, then the index code above would need to
- * pass up a flag to say if any index was truncated during
- * processing as the truncation here refers only to the
- * SCOPE_ONELEVEL index.
- */
- ret = ltdb_index_filter(ltdb, dn_list, ac, match_count,
- scope_one_truncation);
+ ret = ltdb_index_filter(ltdb, dn_list, ac, match_count);
talloc_free(dn_list);
return ret;
}
@@ -2079,8 +1908,6 @@ static int ltdb_index_add1(struct ldb_module *module,
const struct ldb_schema_attribute *a;
struct dn_list *list;
unsigned alloc_len;
- enum key_truncation truncation = KEY_TRUNCATED;
-
ldb = ldb_module_get_ctx(module);
@@ -2090,30 +1917,11 @@ static int ltdb_index_add1(struct ldb_module *module,
}
dn_key = ltdb_index_key(ldb, ltdb,
- el->name, &el->values[v_idx], &a, &truncation);
+ el->name, &el->values[v_idx], &a);
if (!dn_key) {
talloc_free(list);
return LDB_ERR_OPERATIONS_ERROR;
}
- /*
- * Samba only maintains unique indexes on the objectSID and objectGUID
- * so if a unique index key exceeds the maximum length there is a
- * problem.
- */
- if ((truncation == KEY_TRUNCATED) && (a != NULL &&
- (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX ||
- (el->flags & LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX)))) {
-
- ldb_asprintf_errstring(
- ldb,
- __location__ ": unique index key on %s in %s, "
- "exceeds maximum key length of %u (encoded).",
- el->name,
- ldb_dn_get_linearized(msg->dn),
- ltdb->max_key_length);
- talloc_free(list);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
talloc_steal(list, dn_key);
ret = ltdb_dn_list_load(module, ltdb, dn_key, list);
@@ -2130,81 +1938,13 @@ static int ltdb_index_add1(struct ldb_module *module,
* messages.
*/
if (list->count > 0 &&
- ldb_attr_cmp(el->name, LTDB_IDXDN) == 0 &&
- truncation == KEY_NOT_TRUNCATED) {
-
+ ldb_attr_cmp(el->name, LTDB_IDXDN) == 0) {
talloc_free(list);
return LDB_ERR_CONSTRAINT_VIOLATION;
-
- } else if (list->count > 0
- && ldb_attr_cmp(el->name, LTDB_IDXDN) == 0) {
-
- /*
- * At least one existing entry in the DN->GUID index, which
- * arises when the DN indexes have been truncated
- *
- * So need to pull the DN's to check if it's really a duplicate
- */
- int i;
- for (i=0; i < list->count; i++) {
- uint8_t guid_key[LTDB_GUID_KEY_SIZE];
- TDB_DATA key = {
- .dptr = guid_key,
- .dsize = sizeof(guid_key)
- };
- const int flags = LDB_UNPACK_DATA_FLAG_NO_ATTRS;
- struct ldb_message *rec = ldb_msg_new(ldb);
- if (rec == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ret = ltdb_idx_to_key(module, ltdb,
- ldb, &list->dn[i],
- &key);
- if (ret != LDB_SUCCESS) {
- TALLOC_FREE(list);
- TALLOC_FREE(rec);
- return ret;
- }
-
- ret = ltdb_search_key(module, ltdb, key,
- rec, flags);
- if (key.dptr != guid_key) {
- TALLOC_FREE(key.dptr);
- }
- if (ret == LDB_ERR_NO_SUCH_OBJECT) {
- /*
- * the record has disappeared?
- * yes, this can happen
- */
- talloc_free(rec);
- continue;
- }
-
- if (ret != LDB_SUCCESS) {
- /* an internal error */
- TALLOC_FREE(rec);
- TALLOC_FREE(list);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- /*
- * The DN we are trying to add to the DB and index
- * is already here, so we must deny the addition
- */
- if (ldb_dn_compare(msg->dn, rec->dn) == 0) {
- TALLOC_FREE(rec);
- TALLOC_FREE(list);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
- }
}
/*
* Check for duplicates in unique indexes
- *
- * We don't need to do a loop test like the @IDXDN case
- * above as we have a ban on long unique index values
- * at the start of this function.
*/
if (list->count > 0 &&
((a != NULL
@@ -2301,7 +2041,7 @@ static int ltdb_index_add1(struct ldb_module *module,
* forcing in the value with
* LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK
*/
- if (exact != NULL && truncation == KEY_NOT_TRUNCATED) {
+ if (exact != NULL) {
/* This can't fail, gives a default at worst */
const struct ldb_schema_attribute *attr
= ldb_schema_attribute_by_name(
@@ -2601,7 +2341,6 @@ int ltdb_index_del_value(struct ldb_module *module,
unsigned int j;
struct dn_list *list;
struct ldb_dn *dn = msg->dn;
- enum key_truncation truncation = KEY_NOT_TRUNCATED;
ldb = ldb_module_get_ctx(module);
@@ -2615,14 +2354,7 @@ int ltdb_index_del_value(struct ldb_module *module,
}
dn_key = ltdb_index_key(ldb, ltdb,
- el->name, &el->values[v_idx],
- NULL, &truncation);
- /*
- * We ignore key truncation in ltdb_index_add1() so
- * match that by ignoring it here as well
- *
- * Multiple values are legitimate and accepted
- */
+ el->name, &el->values[v_idx], NULL);
if (!dn_key) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -2646,9 +2378,6 @@ int ltdb_index_del_value(struct ldb_module *module,
return ret;
}
- /*
- * Find one of the values matching this message to remove
- */
i = ltdb_dn_list_find_msg(ltdb, list, msg);
if (i == -1) {
/* nothing to delete */
@@ -2764,16 +2493,17 @@ int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg)
commit, which in turn greatly reduces DB churn as we will likely
be able to do a direct update into the old record.
*/
-static int delete_index(struct ltdb_private *ltdb, struct ldb_val key, struct ldb_val data, void *state)
+static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
{
struct ldb_module *module = state;
+ struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
const char *dnstr = "DN=" LTDB_INDEX ":";
struct dn_list list;
struct ldb_dn *dn;
struct ldb_val v;
int ret;
- if (strncmp((char *)key.data, dnstr, strlen(dnstr)) != 0) {
+ if (strncmp((char *)key.dptr, dnstr, strlen(dnstr)) != 0) {
return 0;
}
/* we need to put a empty list in the internal tdb for this
@@ -2782,8 +2512,8 @@ static int delete_index(struct ltdb_private *ltdb, struct ldb_val key, struct ld
list.count = 0;
/* the offset of 3 is to remove the DN= prefix. */
- v.data = key.data + 3;
- v.length = strnlen((char *)key.data, key.length) - 3;
+ v.data = key.dptr + 3;
+ v.length = strnlen((char *)key.dptr, key.dsize) - 3;
dn = ldb_dn_from_ldb_val(ltdb, ldb_module_get_ctx(module), &v);
@@ -2803,23 +2533,29 @@ static int delete_index(struct ltdb_private *ltdb, struct ldb_val key, struct ld
return 0;
}
+struct ltdb_reindex_context {
+ struct ldb_module *module;
+ int error;
+ uint32_t count;
+};
+
/*
- traversal function that adds @INDEX records during a re index TODO wrong comment
+ traversal function that adds @INDEX records during a re index
*/
-static int re_key(struct ltdb_private *ltdb, struct ldb_val ldb_key, struct ldb_val val, void *state)
+static int re_key(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
{
struct ldb_context *ldb;
struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state;
struct ldb_module *module = ctx->module;
struct ldb_message *msg;
unsigned int nb_elements_in_db;
+ const struct ldb_val val = {
+ .data = data.dptr,
+ .length = data.dsize,
+ };
int ret;
TDB_DATA key2;
bool is_record;
- TDB_DATA key = {
- .dptr = ldb_key.data,
- .dsize = ldb_key.length
- };
ldb = ldb_module_get_ctx(module);
@@ -2874,11 +2610,32 @@ static int re_key(struct ltdb_private *ltdb, struct ldb_val ldb_key, struct ldb_
}
if (key.dsize != key2.dsize ||
(memcmp(key.dptr, key2.dptr, key.dsize) != 0)) {
- struct ldb_val ldb_key2 = {
- .data = key2.dptr,
- .length = key2.dsize
- };
- ltdb->kv_ops->update_in_iterate(ltdb, ldb_key, ldb_key2, val, ctx);
+ int tdb_ret;
+ tdb_ret = tdb_delete(tdb, key);
+ if (tdb_ret != 0) {
+ ldb_debug(ldb, LDB_DEBUG_ERROR,
+ "Failed to delete %*.*s "
+ "for rekey as %*.*s: %s",
+ (int)key.dsize, (int)key.dsize,
+ (const char *)key.dptr,
+ (int)key2.dsize, (int)key2.dsize,
+ (const char *)key.dptr,
+ tdb_errorstr(tdb));
+ ctx->error = ltdb_err_map(tdb_error(tdb));
+ return -1;
+ }
+ tdb_ret = tdb_store(tdb, key2, data, 0);
+ if (tdb_ret != 0) {
+ ldb_debug(ldb, LDB_DEBUG_ERROR,
+ "Failed to rekey %*.*s as %*.*s: %s",
+ (int)key.dsize, (int)key.dsize,
+ (const char *)key.dptr,
+ (int)key2.dsize, (int)key2.dsize,
+ (const char *)key.dptr,
+ tdb_errorstr(tdb));
+ ctx->error = ltdb_err_map(tdb_error(tdb));
+ return -1;
+ }
}
talloc_free(key2.dptr);
@@ -2897,16 +2654,18 @@ static int re_key(struct ltdb_private *ltdb, struct ldb_val ldb_key, struct ldb_
/*
traversal function that adds @INDEX records during a re index
*/
-static int re_index(struct ltdb_private *ltdb, struct ldb_val ldb_key, struct ldb_val val, void *state)
+static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
{
struct ldb_context *ldb;
struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state;
struct ldb_module *module = ctx->module;
+ struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module),
+ struct ltdb_private);
struct ldb_message *msg;
unsigned int nb_elements_in_db;
- TDB_DATA key = {
- .dptr = ldb_key.data,
- .dsize = ldb_key.length
+ const struct ldb_val val = {
+ .data = data.dptr,
+ .length = data.dsize,
};
int ret;
bool is_record;
@@ -3016,7 +2775,7 @@ int ltdb_reindex(struct ldb_module *module)
/* first traverse the database deleting any @INDEX records by
* putting NULL entries in the in-memory tdb
*/
- ret = ltdb->kv_ops->iterate(ltdb, delete_index, module);
+ ret = tdb_traverse(ltdb->tdb, delete_index, module);
if (ret < 0) {
struct ldb_context *ldb = ldb_module_get_ctx(module);
ldb_asprintf_errstring(ldb, "index deletion traverse failed: %s",
@@ -3028,7 +2787,8 @@ int ltdb_reindex(struct ldb_module *module)
ctx.error = 0;
ctx.count = 0;
- ret = ltdb->kv_ops->iterate(ltdb, re_key, &ctx);
+ /* now traverse adding any indexes for normal LDB records */
+ ret = tdb_traverse(ltdb->tdb, re_key, &ctx);
if (ret < 0) {
struct ldb_context *ldb = ldb_module_get_ctx(module);
ldb_asprintf_errstring(ldb, "key correction traverse failed: %s",
@@ -3046,7 +2806,7 @@ int ltdb_reindex(struct ldb_module *module)
ctx.count = 0;
/* now traverse adding any indexes for normal LDB records */
- ret = ltdb->kv_ops->iterate(ltdb, re_index, &ctx);
+ ret = tdb_traverse(ltdb->tdb, re_index, &ctx);
if (ret < 0) {
struct ldb_context *ldb = ldb_module_get_ctx(module);
ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s",
@@ -3064,7 +2824,7 @@ int ltdb_reindex(struct ldb_module *module)
ldb_debug(ldb_module_get_ctx(module),
LDB_DEBUG_WARNING, "Reindexing: re_index successful on %s, "
"final index write-out will be in transaction commit",
- ltdb->kv_ops->name(ltdb));
+ tdb_name(ltdb->tdb));
}
return LDB_SUCCESS;
}
diff --git a/ldb_tdb/ldb_search.c b/ldb_tdb/ldb_search.c
index cfc3714..d14be0f 100644
--- a/ldb_tdb/ldb_search.c
+++ b/ldb_tdb/ldb_search.c
@@ -102,8 +102,11 @@ static int msg_add_distinguished_name(struct ldb_message *msg)
el.values = &val;
el.flags = 0;
val.data = (uint8_t *)ldb_dn_alloc_linearized(msg, msg->dn);
+ if (val.data == NULL) {
+ return -1;
+ }
val.length = strlen((char *)val.data);
-
+
ret = msg_add_element(msg, &el, 1);
return ret;
}
@@ -180,15 +183,17 @@ struct ltdb_parse_data_unpack_ctx {
unsigned int unpack_flags;
};
-static int ltdb_parse_data_unpack(struct ldb_val key,
- struct ldb_val data,
+static int ltdb_parse_data_unpack(TDB_DATA key, TDB_DATA data,
void *private_data)
{
struct ltdb_parse_data_unpack_ctx *ctx = private_data;
unsigned int nb_elements_in_db;
int ret;
struct ldb_context *ldb = ldb_module_get_ctx(ctx->module);
- struct ldb_val data_parse = data;
+ struct ldb_val data_parse = {
+ .data = data.dptr,
+ .length = data.dsize
+ };
if (ctx->unpack_flags & LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC) {
/*
@@ -198,13 +203,13 @@ static int ltdb_parse_data_unpack(struct ldb_val key,
* and the caller needs a stable result.
*/
data_parse.data = talloc_memdup(ctx->msg,
- data.data,
- data.length);
+ data.dptr,
+ data.dsize);
if (data_parse.data == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
"Unable to allocate data(%d) for %*.*s\n",
- (int)data.length,
- (int)key.length, (int)key.length, key.data);
+ (int)data.dsize,
+ (int)key.dsize, (int)key.dsize, key.dptr);
return LDB_ERR_OPERATIONS_ERROR;
}
}
@@ -215,13 +220,13 @@ static int ltdb_parse_data_unpack(struct ldb_val key,
ctx->unpack_flags,
&nb_elements_in_db);
if (ret == -1) {
- if (data_parse.data != data.data) {
+ if (data_parse.data != data.dptr) {
talloc_free(data_parse.data);
}
ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %*.*s\n",
- (int)key.length, (int)key.length, key.data);
- return LDB_ERR_OPERATIONS_ERROR;
+ (int)key.dsize, (int)key.dsize, key.dptr);
+ return LDB_ERR_OPERATIONS_ERROR;
}
return ret;
}
@@ -244,21 +249,17 @@ int ltdb_search_key(struct ldb_module *module, struct ltdb_private *ltdb,
.module = module,
.unpack_flags = unpack_flags
};
- struct ldb_val ldb_key = {
- .data = tdb_key.dptr,
- .length = tdb_key.dsize
- };
memset(msg, 0, sizeof(*msg));
msg->num_elements = 0;
msg->elements = NULL;
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, ldb_key,
- ltdb_parse_data_unpack, &ctx);
-
+ ret = tdb_parse_record(ltdb->tdb, tdb_key,
+ ltdb_parse_data_unpack, &ctx);
+
if (ret == -1) {
- ret = ltdb->kv_ops->error(ltdb);
+ ret = ltdb_err_map(tdb_error(ltdb->tdb));
if (ret == LDB_SUCCESS) {
/*
* Just to be sure we don't turn errors
@@ -294,9 +295,27 @@ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_mes
};
TALLOC_CTX *tdb_key_ctx = NULL;
- if (ltdb->cache->GUID_index_attribute == NULL ||
- ldb_dn_is_special(dn)) {
+ bool valid_dn = ldb_dn_validate(dn);
+ if (valid_dn == false) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Invalid Base DN: %s",
+ ldb_dn_get_linearized(dn));
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+ if (ltdb->cache->GUID_index_attribute == NULL) {
+ tdb_key_ctx = talloc_new(msg);
+ if (!tdb_key_ctx) {
+ return ldb_module_oom(module);
+ }
+
+ /* form the key */
+ tdb_key = ltdb_key_dn(module, tdb_key_ctx, dn);
+ if (!tdb_key.dptr) {
+ TALLOC_FREE(tdb_key_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ } else if (ldb_dn_is_special(dn)) {
tdb_key_ctx = talloc_new(msg);
if (!tdb_key_ctx) {
return ldb_module_oom(module);
@@ -397,7 +416,7 @@ int ltdb_filter_attrs(TALLOC_CTX *mem_ctx,
/* Shortcuts for the simple cases */
} else if (add_dn && i == 1) {
if (msg_add_distinguished_name(msg2) != 0) {
- return -1;
+ goto failed;
}
*filtered_msg = msg2;
return 0;
@@ -463,7 +482,7 @@ int ltdb_filter_attrs(TALLOC_CTX *mem_ctx,
if (add_dn) {
if (msg_add_distinguished_name(msg2) != 0) {
- return -1;
+ goto failed;
}
}
@@ -472,7 +491,7 @@ int ltdb_filter_attrs(TALLOC_CTX *mem_ctx,
struct ldb_message_element,
msg2->num_elements);
if (msg2->elements == NULL) {
- return -1;
+ goto failed;
}
} else {
talloc_free(msg2->elements);
@@ -483,29 +502,30 @@ int ltdb_filter_attrs(TALLOC_CTX *mem_ctx,
return 0;
failed:
+ TALLOC_FREE(msg2);
return -1;
}
/*
search function for a non-indexed search
*/
-static int search_func(struct ltdb_private *ltdb, struct ldb_val key, struct ldb_val val, void *state)
+static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
{
struct ldb_context *ldb;
struct ltdb_context *ac;
struct ldb_message *msg, *filtered_msg;
+ const struct ldb_val val = {
+ .data = data.dptr,
+ .length = data.dsize,
+ };
int ret;
bool matched;
unsigned int nb_elements_in_db;
- TDB_DATA tdb_key = {
- .dptr = key.data,
- .dsize = key.length
- };
ac = talloc_get_type(state, struct ltdb_context);
ldb = ldb_module_get_ctx(ac->module);
- if (ltdb_key_is_record(tdb_key) == false) {
+ if (ltdb_key_is_record(key) == false) {
return 0;
}
@@ -530,7 +550,7 @@ static int search_func(struct ltdb_private *ltdb, struct ldb_val key, struct ldb
if (!msg->dn) {
msg->dn = ldb_dn_new(msg, ldb,
- (char *)key.data + 3);
+ (char *)key.dptr + 3);
if (msg->dn == NULL) {
talloc_free(msg);
ac->error = LDB_ERR_OPERATIONS_ERROR;
@@ -583,7 +603,11 @@ static int ltdb_search_full(struct ltdb_context *ctx)
int ret;
ctx->error = LDB_SUCCESS;
- ret = ltdb->kv_ops->iterate(ltdb, search_func, ctx);
+ if (ltdb->in_transaction != 0) {
+ ret = tdb_traverse(ltdb->tdb, search_func, ctx);
+ } else {
+ ret = tdb_traverse_read(ltdb->tdb, search_func, ctx);
+ }
if (ret < 0) {
return LDB_ERR_OPERATIONS_ERROR;
@@ -709,17 +733,17 @@ int ltdb_search(struct ltdb_context *ctx)
ldb_request_set_state(req, LDB_ASYNC_PENDING);
- if (ltdb->kv_ops->lock_read(module) != 0) {
+ if (ltdb_lock_read(module) != 0) {
return LDB_ERR_OPERATIONS_ERROR;
}
if (ltdb_cache_load(module) != 0) {
- ltdb->kv_ops->unlock_read(module);
+ ltdb_unlock_read(module);
return LDB_ERR_OPERATIONS_ERROR;
}
if (req->op.search.tree == NULL) {
- ltdb->kv_ops->unlock_read(module);
+ ltdb_unlock_read(module);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -766,7 +790,7 @@ int ltdb_search(struct ltdb_context *ctx)
*/
ret = ltdb_search_and_return_base(ltdb, ctx);
- ltdb->kv_ops->unlock_read(module);
+ ltdb_unlock_read(module);
return ret;
@@ -787,6 +811,14 @@ int ltdb_search(struct ltdb_context *ctx)
ldb_dn_get_linearized(req->op.search.base));
}
+ } else if (ldb_dn_validate(req->op.search.base) == false) {
+
+ /* We don't want invalid base DNs here */
+ ldb_asprintf_errstring(ldb,
+ "Invalid Base DN: %s",
+ ldb_dn_get_linearized(req->op.search.base));
+ ret = LDB_ERR_INVALID_DN_SYNTAX;
+
} else {
/* If we are not checking the base DN life is easy */
ret = LDB_SUCCESS;
@@ -829,14 +861,14 @@ int ltdb_search(struct ltdb_context *ctx)
* full search or we may return
* duplicate entries
*/
- ltdb->kv_ops->unlock_read(module);
+ ltdb_unlock_read(module);
return LDB_ERR_OPERATIONS_ERROR;
}
if (ltdb->disable_full_db_scan) {
ldb_set_errstring(ldb,
"ldb FULL SEARCH disabled");
- ltdb->kv_ops->unlock_read(module);
+ ltdb_unlock_read(module);
return LDB_ERR_INAPPROPRIATE_MATCHING;
}
@@ -847,7 +879,7 @@ int ltdb_search(struct ltdb_context *ctx)
}
}
- ltdb->kv_ops->unlock_read(module);
+ ltdb_unlock_read(module);
return ret;
}
diff --git a/ldb_tdb/ldb_tdb.c b/ldb_tdb/ldb_tdb.c
index 8581604..c7bf865 100644
--- a/ldb_tdb/ldb_tdb.c
+++ b/ldb_tdb/ldb_tdb.c
@@ -94,25 +94,14 @@ int ltdb_err_map(enum TDB_ERROR tdb_code)
/*
lock the database for read - use by ltdb_search and ltdb_sequence_number
*/
-static int ltdb_lock_read(struct ldb_module *module)
+int ltdb_lock_read(struct ldb_module *module)
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
int tdb_ret = 0;
int ret;
- pid_t pid = getpid();
-
- if (ltdb->pid != pid) {
- ldb_asprintf_errstring(
- ldb_module_get_ctx(module),
- __location__": Reusing ldb opend by pid %d in "
- "process %d\n",
- ltdb->pid,
- pid);
- return LDB_ERR_PROTOCOL_ERROR;
- }
- if (tdb_transaction_active(ltdb->tdb) == false &&
+ if (ltdb->in_transaction == 0 &&
ltdb->read_lock_count == 0) {
tdb_ret = tdb_lockall_read(ltdb->tdb);
}
@@ -135,22 +124,11 @@ static int ltdb_lock_read(struct ldb_module *module)
/*
unlock the database after a ltdb_lock_read()
*/
-static int ltdb_unlock_read(struct ldb_module *module)
+int ltdb_unlock_read(struct ldb_module *module)
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- pid_t pid = getpid();
-
- if (ltdb->pid != pid) {
- ldb_asprintf_errstring(
- ldb_module_get_ctx(module),
- __location__": Reusing ldb opend by pid %d in "
- "process %d\n",
- ltdb->pid,
- pid);
- return LDB_ERR_PROTOCOL_ERROR;
- }
- if (!tdb_transaction_active(ltdb->tdb) && ltdb->read_lock_count == 1) {
+ if (ltdb->in_transaction == 0 && ltdb->read_lock_count == 1) {
tdb_unlockall_read(ltdb->tdb);
ltdb->read_lock_count--;
return 0;
@@ -401,7 +379,7 @@ static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
/* only allow modifies inside a transaction, otherwise the
* ldb is unsafe */
- if (ltdb->kv_ops->transaction_active(ltdb) == false) {
+ if (ltdb->in_transaction == 0) {
ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction");
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -413,7 +391,7 @@ static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
if (ltdb->warn_reindex) {
ldb_debug(ldb_module_get_ctx(module),
LDB_DEBUG_ERROR, "Reindexing %s due to modification on %s",
- ltdb->kv_ops->name(ltdb), ldb_dn_get_linearized(dn));
+ tdb_name(ltdb->tdb), ldb_dn_get_linearized(dn));
}
ret = ltdb_reindex(module);
}
@@ -439,34 +417,6 @@ static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
return ret;
}
-static int ltdb_tdb_store(struct ltdb_private *ltdb, struct ldb_val ldb_key,
- struct ldb_val ldb_data, int flags)
-{
- TDB_DATA key = {
- .dptr = ldb_key.data,
- .dsize = ldb_key.length
- };
- TDB_DATA data = {
- .dptr = ldb_data.data,
- .dsize = ldb_data.length
- };
- bool transaction_active = tdb_transaction_active(ltdb->tdb);
- if (transaction_active == false){
- return LDB_ERR_PROTOCOL_ERROR;
- }
- return tdb_store(ltdb->tdb, key, data, flags);
-}
-
-static int ltdb_error(struct ltdb_private *ltdb)
-{
- return ltdb_err_map(tdb_error(ltdb->tdb));
-}
-
-static const char *ltdb_errorstr(struct ltdb_private *ltdb)
-{
- return tdb_errorstr(ltdb->tdb);
-}
-
/*
store a record into the db
*/
@@ -474,8 +424,7 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- TDB_DATA tdb_key;
- struct ldb_val ldb_key;
+ TDB_DATA tdb_key, tdb_data;
struct ldb_val ldb_data;
int ret = LDB_SUCCESS;
TALLOC_CTX *tdb_key_ctx = talloc_new(module);
@@ -485,6 +434,7 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg
}
if (ltdb->read_only) {
+ talloc_free(tdb_key_ctx);
return LDB_ERR_UNWILLING_TO_PERFORM;
}
@@ -501,13 +451,13 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg
return LDB_ERR_OTHER;
}
- ldb_key.data = tdb_key.dptr;
- ldb_key.length = tdb_key.dsize;
+ tdb_data.dptr = ldb_data.data;
+ tdb_data.dsize = ldb_data.length;
- ret = ltdb->kv_ops->store(ltdb, ldb_key, ldb_data, flgs);
+ ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
if (ret != 0) {
bool is_special = ldb_dn_is_special(msg->dn);
- ret = ltdb->kv_ops->error(ltdb);
+ ret = ltdb_err_map(tdb_error(ltdb->tdb));
/*
* LDB_ERR_ENTRY_ALREADY_EXISTS means the DN, not
@@ -565,6 +515,16 @@ static int ltdb_add_internal(struct ldb_module *module,
struct ldb_context *ldb = ldb_module_get_ctx(module);
int ret = LDB_SUCCESS;
unsigned int i;
+ bool valid_dn = false;
+
+ /* Check the new DN is reasonable */
+ valid_dn = ldb_dn_validate(msg->dn);
+ if (valid_dn == false) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Invalid DN in ADD: %s",
+ ldb_dn_get_linearized(msg->dn));
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
for (i=0;i<msg->num_elements;i++) {
struct ldb_message_element *el = &msg->elements[i];
@@ -626,7 +586,7 @@ static int ltdb_add_internal(struct ldb_module *module,
if (mem_ctx == NULL) {
return ldb_module_operr(module);
}
- ret2 = ltdb_search_base(module, module,
+ ret2 = ltdb_search_base(module, mem_ctx,
msg->dn, &dn2);
TALLOC_FREE(mem_ctx);
if (ret2 == LDB_SUCCESS) {
@@ -673,16 +633,6 @@ static int ltdb_add(struct ltdb_context *ctx)
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
int ret = LDB_SUCCESS;
- if (ltdb->max_key_length != 0 &&
- ltdb->cache->GUID_index_attribute == NULL &&
- !ldb_dn_is_special(req->op.add.message->dn))
- {
- ldb_set_errstring(ldb_module_get_ctx(module),
- "Must operate ldb_mdb in GUID "
- "index mode, but " LTDB_IDXGUID " not set.");
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
-
ret = ltdb_check_special_dn(module, req->op.add.message);
if (ret != LDB_SUCCESS) {
return ret;
@@ -700,19 +650,6 @@ static int ltdb_add(struct ltdb_context *ctx)
return ret;
}
-static int ltdb_tdb_delete(struct ltdb_private *ltdb, struct ldb_val ldb_key)
-{
- TDB_DATA tdb_key = {
- .dptr = ldb_key.data,
- .dsize = ldb_key.length
- };
- bool transaction_active = tdb_transaction_active(ltdb->tdb);
- if (transaction_active == false){
- return LDB_ERR_PROTOCOL_ERROR;
- }
- return tdb_delete(ltdb->tdb, tdb_key);
-}
-
/*
delete a record from the database, not updating indexes (used for deleting
index records)
@@ -722,7 +659,6 @@ int ltdb_delete_noindex(struct ldb_module *module,
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- struct ldb_val ldb_key;
TDB_DATA tdb_key;
int ret;
TALLOC_CTX *tdb_key_ctx = talloc_new(module);
@@ -732,6 +668,7 @@ int ltdb_delete_noindex(struct ldb_module *module,
}
if (ltdb->read_only) {
+ talloc_free(tdb_key_ctx);
return LDB_ERR_UNWILLING_TO_PERFORM;
}
@@ -741,14 +678,11 @@ int ltdb_delete_noindex(struct ldb_module *module,
return LDB_ERR_OTHER;
}
- ldb_key.data = tdb_key.dptr;
- ldb_key.length = tdb_key.dsize;
-
- ret = ltdb->kv_ops->delete(ltdb, ldb_key);
+ ret = tdb_delete(ltdb->tdb, tdb_key);
TALLOC_FREE(tdb_key_ctx);
if (ret != 0) {
- ret = ltdb->kv_ops->error(ltdb);
+ ret = ltdb_err_map(tdb_error(ltdb->tdb));
}
return ret;
@@ -988,6 +922,7 @@ static int msg_delete_element(struct ldb_module *module,
return LDB_ERR_NO_SUCH_ATTRIBUTE;
}
+
/*
modify a record - internal interface
@@ -1367,6 +1302,7 @@ static int ltdb_rename(struct ltdb_context *ctx)
int ret = LDB_SUCCESS;
TDB_DATA tdb_key, tdb_key_old;
struct ldb_dn *db_dn;
+ bool valid_dn = false;
ldb_request_set_state(req, LDB_ASYNC_PENDING);
@@ -1379,10 +1315,24 @@ static int ltdb_rename(struct ltdb_context *ctx)
return LDB_ERR_OPERATIONS_ERROR;
}
+ /* Check the new DN is reasonable */
+ valid_dn = ldb_dn_validate(req->op.rename.newdn);
+ if (valid_dn == false) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Invalid New DN: %s",
+ ldb_dn_get_linearized(req->op.rename.newdn));
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+
/* we need to fetch the old record to re-add under the new name */
ret = ltdb_search_dn1(module, req->op.rename.olddn, msg,
LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC);
- if (ret != LDB_SUCCESS) {
+ if (ret == LDB_ERR_INVALID_DN_SYNTAX) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Invalid Old DN: %s",
+ ldb_dn_get_linearized(req->op.rename.newdn));
+ return ret;
+ } else if (ret != LDB_SUCCESS) {
/* not finding the old record is an error */
return ret;
}
@@ -1467,100 +1417,21 @@ static int ltdb_rename(struct ltdb_context *ctx)
return ret;
}
-static int ltdb_tdb_transaction_start(struct ltdb_private *ltdb)
-{
- pid_t pid = getpid();
-
- if (ltdb->pid != pid) {
- ldb_asprintf_errstring(
- ldb_module_get_ctx(ltdb->module),
- __location__": Reusing ldb opend by pid %d in "
- "process %d\n",
- ltdb->pid,
- pid);
- return LDB_ERR_PROTOCOL_ERROR;
- }
-
- return tdb_transaction_start(ltdb->tdb);
-}
-
-static int ltdb_tdb_transaction_cancel(struct ltdb_private *ltdb)
-{
- pid_t pid = getpid();
-
- if (ltdb->pid != pid) {
- ldb_asprintf_errstring(
- ldb_module_get_ctx(ltdb->module),
- __location__": Reusing ldb opend by pid %d in "
- "process %d\n",
- ltdb->pid,
- pid);
- return LDB_ERR_PROTOCOL_ERROR;
- }
-
- return tdb_transaction_cancel(ltdb->tdb);
-}
-
-static int ltdb_tdb_transaction_prepare_commit(struct ltdb_private *ltdb)
-{
- pid_t pid = getpid();
-
- if (ltdb->pid != pid) {
- ldb_asprintf_errstring(
- ldb_module_get_ctx(ltdb->module),
- __location__": Reusing ldb opend by pid %d in "
- "process %d\n",
- ltdb->pid,
- pid);
- return LDB_ERR_PROTOCOL_ERROR;
- }
-
- return tdb_transaction_prepare_commit(ltdb->tdb);
-}
-
-static int ltdb_tdb_transaction_commit(struct ltdb_private *ltdb)
-{
- pid_t pid = getpid();
-
- if (ltdb->pid != pid) {
- ldb_asprintf_errstring(
- ldb_module_get_ctx(ltdb->module),
- __location__": Reusing ldb opend by pid %d in "
- "process %d\n",
- ltdb->pid,
- pid);
- return LDB_ERR_PROTOCOL_ERROR;
- }
-
- return tdb_transaction_commit(ltdb->tdb);
-}
-
static int ltdb_start_trans(struct ldb_module *module)
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- pid_t pid = getpid();
-
- if (ltdb->pid != pid) {
- ldb_asprintf_errstring(
- ldb_module_get_ctx(ltdb->module),
- __location__": Reusing ldb opend by pid %d in "
- "process %d\n",
- ltdb->pid,
- pid);
- return LDB_ERR_PROTOCOL_ERROR;
- }
-
/* Do not take out the transaction lock on a read-only DB */
if (ltdb->read_only) {
return LDB_ERR_UNWILLING_TO_PERFORM;
}
- if (ltdb->kv_ops->begin_write(ltdb) != 0) {
- return ltdb->kv_ops->error(ltdb);
+ if (tdb_transaction_start(ltdb->tdb) != 0) {
+ return ltdb_err_map(tdb_error(ltdb->tdb));
}
+ ltdb->in_transaction++;
ltdb_index_transaction_start(module);
@@ -1580,23 +1451,9 @@ static int ltdb_prepare_commit(struct ldb_module *module)
int ret;
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- pid_t pid = getpid();
-
- if (ltdb->pid != pid) {
- ldb_asprintf_errstring(
- ldb_module_get_ctx(module),
- __location__": Reusing ldb opend by pid %d in "
- "process %d\n",
- ltdb->pid,
- pid);
- return LDB_ERR_PROTOCOL_ERROR;
- }
- if (!ltdb->kv_ops->transaction_active(ltdb)) {
- ldb_set_errstring(ldb_module_get_ctx(module),
- "ltdb_prepare_commit() called "
- "without transaction active");
- return LDB_ERR_OPERATIONS_ERROR;
+ if (ltdb->in_transaction != 1) {
+ return LDB_SUCCESS;
}
/*
@@ -1619,17 +1476,19 @@ static int ltdb_prepare_commit(struct ldb_module *module)
ret = ltdb_index_transaction_commit(module);
if (ret != LDB_SUCCESS) {
- ltdb->kv_ops->abort_write(ltdb);
+ tdb_transaction_cancel(ltdb->tdb);
+ ltdb->in_transaction--;
return ret;
}
- if (ltdb->kv_ops->prepare_write(ltdb) != 0) {
- ret = ltdb->kv_ops->error(ltdb);
+ if (tdb_transaction_prepare_commit(ltdb->tdb) != 0) {
+ ret = ltdb_err_map(tdb_error(ltdb->tdb));
+ ltdb->in_transaction--;
ldb_debug_set(ldb_module_get_ctx(module),
LDB_DEBUG_FATAL,
"Failure during "
- "prepare_write): %s -> %s",
- ltdb->kv_ops->errorstr(ltdb),
+ "tdb_transaction_prepare_commit(): %s -> %s",
+ tdb_errorstr(ltdb->tdb),
ldb_strerror(ret));
return ret;
}
@@ -1652,13 +1511,14 @@ static int ltdb_end_trans(struct ldb_module *module)
}
}
+ ltdb->in_transaction--;
ltdb->prepared_commit = false;
- if (ltdb->kv_ops->finish_write(ltdb) != 0) {
- ret = ltdb->kv_ops->error(ltdb);
+ if (tdb_transaction_commit(ltdb->tdb) != 0) {
+ ret = ltdb_err_map(tdb_error(ltdb->tdb));
ldb_asprintf_errstring(ldb_module_get_ctx(module),
"Failure during tdb_transaction_commit(): %s -> %s",
- ltdb->kv_ops->errorstr(ltdb),
+ tdb_errorstr(ltdb->tdb),
ldb_strerror(ret));
return ret;
}
@@ -1671,13 +1531,14 @@ static int ltdb_del_trans(struct ldb_module *module)
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
+ ltdb->in_transaction--;
if (ltdb_index_transaction_cancel(module) != 0) {
- ltdb->kv_ops->abort_write(ltdb);
- return ltdb->kv_ops->error(ltdb);
+ tdb_transaction_cancel(ltdb->tdb);
+ return ltdb_err_map(tdb_error(ltdb->tdb));
}
- ltdb->kv_ops->abort_write(ltdb);
+ tdb_transaction_cancel(ltdb->tdb);
return LDB_SUCCESS;
}
@@ -1690,8 +1551,6 @@ static int ltdb_sequence_number(struct ltdb_context *ctx,
struct ldb_context *ldb;
struct ldb_module *module = ctx->module;
struct ldb_request *req = ctx->req;
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
TALLOC_CTX *tmp_ctx = NULL;
struct ldb_seqnum_request *seq;
struct ldb_seqnum_result *res;
@@ -1710,7 +1569,7 @@ static int ltdb_sequence_number(struct ltdb_context *ctx,
ldb_request_set_state(req, LDB_ASYNC_PENDING);
- if (ltdb->kv_ops->lock_read(module) != 0) {
+ if (ltdb_lock_read(module) != 0) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -1772,8 +1631,7 @@ static int ltdb_sequence_number(struct ltdb_context *ctx,
done:
talloc_free(tmp_ctx);
-
- ltdb->kv_ops->unlock_read(module);
+ ltdb_unlock_read(module);
return ret;
}
@@ -1870,181 +1728,6 @@ static void ltdb_handle_extended(struct ltdb_context *ctx)
ltdb_request_extended_done(ctx, ext, ret);
}
-struct kv_ctx {
- ldb_kv_traverse_fn kv_traverse_fn;
- void *ctx;
- struct ltdb_private *ltdb;
- int (*parser)(struct ldb_val key,
- struct ldb_val data,
- void *private_data);
-};
-
-static int ldb_tdb_traverse_fn_wrapper(struct tdb_context *tdb, TDB_DATA tdb_key, TDB_DATA tdb_data, void *ctx)
-{
- struct kv_ctx *kv_ctx = ctx;
- struct ldb_val key = {
- .length = tdb_key.dsize,
- .data = tdb_key.dptr,
- };
- struct ldb_val data = {
- .length = tdb_data.dsize,
- .data = tdb_data.dptr,
- };
- return kv_ctx->kv_traverse_fn(kv_ctx->ltdb, key, data, kv_ctx->ctx);
-}
-
-static int ltdb_tdb_traverse_fn(struct ltdb_private *ltdb, ldb_kv_traverse_fn fn, void *ctx)
-{
- struct kv_ctx kv_ctx = {
- .kv_traverse_fn = fn,
- .ctx = ctx,
- .ltdb = ltdb
- };
- if (tdb_transaction_active(ltdb->tdb)) {
- return tdb_traverse(ltdb->tdb, ldb_tdb_traverse_fn_wrapper, &kv_ctx);
- } else {
- return tdb_traverse_read(ltdb->tdb, ldb_tdb_traverse_fn_wrapper, &kv_ctx);
- }
-}
-
-static int ltdb_tdb_update_in_iterate(struct ltdb_private *ltdb,
- struct ldb_val ldb_key,
- struct ldb_val ldb_key2,
- struct ldb_val ldb_data, void *state)
-{
- int tdb_ret;
- struct ldb_context *ldb;
- struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state;
- struct ldb_module *module = ctx->module;
- TDB_DATA key = {
- .dptr = ldb_key.data,
- .dsize = ldb_key.length
- };
- TDB_DATA key2 = {
- .dptr = ldb_key2.data,
- .dsize = ldb_key2.length
- };
- TDB_DATA data = {
- .dptr = ldb_data.data,
- .dsize = ldb_data.length
- };
-
- ldb = ldb_module_get_ctx(module);
-
- tdb_ret = tdb_delete(ltdb->tdb, key);
- if (tdb_ret != 0) {
- ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Failed to delete %*.*s "
- "for rekey as %*.*s: %s",
- (int)key.dsize, (int)key.dsize,
- (const char *)key.dptr,
- (int)key2.dsize, (int)key2.dsize,
- (const char *)key.dptr,
- tdb_errorstr(ltdb->tdb));
- ctx->error = ltdb_err_map(tdb_error(ltdb->tdb));
- return -1;
- }
- tdb_ret = tdb_store(ltdb->tdb, key2, data, 0);
- if (tdb_ret != 0) {
- ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Failed to rekey %*.*s as %*.*s: %s",
- (int)key.dsize, (int)key.dsize,
- (const char *)key.dptr,
- (int)key2.dsize, (int)key2.dsize,
- (const char *)key.dptr,
- tdb_errorstr(ltdb->tdb));
- ctx->error = ltdb_err_map(tdb_error(ltdb->tdb));
- return -1;
- }
- return tdb_ret;
-}
-
-static int ltdb_tdb_parse_record_wrapper(TDB_DATA tdb_key, TDB_DATA tdb_data,
- void *ctx)
-{
- struct kv_ctx *kv_ctx = ctx;
- struct ldb_val key = {
- .length = tdb_key.dsize,
- .data = tdb_key.dptr,
- };
- struct ldb_val data = {
- .length = tdb_data.dsize,
- .data = tdb_data.dptr,
- };
-
- return kv_ctx->parser(key, data, kv_ctx->ctx);
-}
-
-static int ltdb_tdb_parse_record(struct ltdb_private *ltdb,
- struct ldb_val ldb_key,
- int (*parser)(struct ldb_val key,
- struct ldb_val data,
- void *private_data),
- void *ctx)
-{
- struct kv_ctx kv_ctx = {
- .parser = parser,
- .ctx = ctx,
- .ltdb = ltdb
- };
- TDB_DATA key = {
- .dptr = ldb_key.data,
- .dsize = ldb_key.length
- };
- int ret;
-
- if (tdb_transaction_active(ltdb->tdb) == false &&
- ltdb->read_lock_count == 0) {
- return LDB_ERR_PROTOCOL_ERROR;
- }
-
- ret = tdb_parse_record(ltdb->tdb, key, ltdb_tdb_parse_record_wrapper,
- &kv_ctx);
- if (ret == 0) {
- return LDB_SUCCESS;
- }
- return ltdb_err_map(tdb_error(ltdb->tdb));
-}
-
-static const char * ltdb_tdb_name(struct ltdb_private *ltdb)
-{
- return tdb_name(ltdb->tdb);
-}
-
-static bool ltdb_tdb_changed(struct ltdb_private *ltdb)
-{
- int seq = tdb_get_seqnum(ltdb->tdb);
- bool has_changed = (seq != ltdb->tdb_seqnum);
-
- ltdb->tdb_seqnum = seq;
-
- return has_changed;
-}
-
-static bool ltdb_transaction_active(struct ltdb_private *ltdb)
-{
- return tdb_transaction_active(ltdb->tdb);
-}
-
-static const struct kv_db_ops key_value_ops = {
- .store = ltdb_tdb_store,
- .delete = ltdb_tdb_delete,
- .iterate = ltdb_tdb_traverse_fn,
- .update_in_iterate = ltdb_tdb_update_in_iterate,
- .fetch_and_parse = ltdb_tdb_parse_record,
- .lock_read = ltdb_lock_read,
- .unlock_read = ltdb_unlock_read,
- .begin_write = ltdb_tdb_transaction_start,
- .prepare_write = ltdb_tdb_transaction_prepare_commit,
- .finish_write = ltdb_tdb_transaction_commit,
- .abort_write = ltdb_tdb_transaction_cancel,
- .error = ltdb_error,
- .errorstr = ltdb_errorstr,
- .name = ltdb_tdb_name,
- .has_changed = ltdb_tdb_changed,
- .transaction_active = ltdb_transaction_active,
-};
-
static void ltdb_callback(struct tevent_context *ev,
struct tevent_timer *te,
struct timeval t,
@@ -2193,21 +1876,6 @@ static int ltdb_init_rootdse(struct ldb_module *module)
return LDB_SUCCESS;
}
-
-static int generic_lock_read(struct ldb_module *module)
-{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- return ltdb->kv_ops->lock_read(module);
-}
-
-static int generic_unlock_read(struct ldb_module *module)
-{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- return ltdb->kv_ops->unlock_read(module);
-}
-
static const struct ldb_module_ops ltdb_ops = {
.name = "tdb",
.init_context = ltdb_init_rootdse,
@@ -2221,90 +1889,18 @@ static const struct ldb_module_ops ltdb_ops = {
.end_transaction = ltdb_end_trans,
.prepare_commit = ltdb_prepare_commit,
.del_transaction = ltdb_del_trans,
- .read_lock = generic_lock_read,
- .read_unlock = generic_unlock_read,
+ .read_lock = ltdb_lock_read,
+ .read_unlock = ltdb_unlock_read,
};
-int init_store(struct ltdb_private *ltdb,
- const char *name,
- struct ldb_context *ldb,
- const char *options[],
- struct ldb_module **_module)
-{
- if (getenv("LDB_WARN_UNINDEXED")) {
- ltdb->warn_unindexed = true;
- }
-
- if (getenv("LDB_WARN_REINDEX")) {
- ltdb->warn_reindex = true;
- }
-
- ltdb->sequence_number = 0;
-
- ltdb->pid = getpid();
-
- ltdb->module = ldb_module_new(ldb, ldb, name, &ltdb_ops);
- if (!ltdb->module) {
- ldb_oom(ldb);
- talloc_free(ltdb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ldb_module_set_private(ltdb->module, ltdb);
- talloc_steal(ltdb->module, ltdb);
-
- if (ltdb_cache_load(ltdb->module) != 0) {
- ldb_asprintf_errstring(ldb, "Unable to load ltdb cache "
- "records for backend '%s'", name);
- talloc_free(ltdb->module);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- *_module = ltdb->module;
- /*
- * Set or override the maximum key length
- *
- * The ldb_mdb code will have set this to 511, but our tests
- * set this even smaller (to make the tests more practical).
- *
- * This must only be used for the selftest as the length
- * becomes encoded in the index keys.
- */
- {
- const char *len_str =
- ldb_options_find(ldb, options,
- "max_key_len_for_self_test");
- if (len_str != NULL) {
- unsigned len = strtoul(len_str, NULL, 0);
- ltdb->max_key_length = len;
- }
- }
-
- /*
- * Override full DB scans
- *
- * A full DB scan is expensive on a large database. This
- * option is for testing to show that the full DB scan is not
- * triggered.
- */
- {
- const char *len_str =
- ldb_options_find(ldb, options,
- "disable_full_db_scan_for_self_test");
- if (len_str != NULL) {
- ltdb->disable_full_db_scan = true;
- }
- }
-
- return LDB_SUCCESS;
-}
-
/*
connect to the database
*/
-int ltdb_connect(struct ldb_context *ldb, const char *url,
- unsigned int flags, const char *options[],
- struct ldb_module **_module)
+static int ltdb_connect(struct ldb_context *ldb, const char *url,
+ unsigned int flags, const char *options[],
+ struct ldb_module **_module)
{
+ struct ldb_module *module;
const char *path;
int tdb_flags, open_flags;
struct ltdb_private *ltdb;
@@ -2313,6 +1909,7 @@ int ltdb_connect(struct ldb_context *ldb, const char *url,
* We hold locks, so we must use a private event context
* on each returned handle
*/
+
ldb_set_require_private_event_context(ldb);
/* parse the url */
@@ -2327,7 +1924,7 @@ int ltdb_connect(struct ldb_context *ldb, const char *url,
path = url;
}
- tdb_flags = TDB_DEFAULT | TDB_SEQNUM | TDB_DISALLOW_NESTING;
+ tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
/* check for the 'nosync' option */
if (flags & LDB_FLG_NOSYNC) {
@@ -2369,9 +1966,6 @@ int ltdb_connect(struct ldb_context *ldb, const char *url,
open_flags = O_CREAT | O_RDWR;
}
- ltdb->kv_ops = &key_value_ops;
-
- errno = 0;
/* note that we use quite a large default hash size */
ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
tdb_flags, open_flags,
@@ -2388,5 +1982,54 @@ int ltdb_connect(struct ldb_context *ldb, const char *url,
return LDB_ERR_OPERATIONS_ERROR;
}
- return init_store(ltdb, "ldb_tdb backend", ldb, options, _module);
+ if (getenv("LDB_WARN_UNINDEXED")) {
+ ltdb->warn_unindexed = true;
+ }
+
+ if (getenv("LDB_WARN_REINDEX")) {
+ ltdb->warn_reindex = true;
+ }
+
+ ltdb->sequence_number = 0;
+
+ /*
+ * Override full DB scans
+ *
+ * A full DB scan is expensive on a large database. This
+ * option is for testing to show that the full DB scan is not
+ * triggered.
+ */
+ {
+ const char *len_str =
+ ldb_options_find(ldb, options,
+ "disable_full_db_scan_for_self_test");
+ if (len_str != NULL) {
+ ltdb->disable_full_db_scan = true;
+ }
+ }
+
+ module = ldb_module_new(ldb, ldb, "ldb_tdb backend", &ltdb_ops);
+ if (!module) {
+ ldb_oom(ldb);
+ talloc_free(ltdb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ ldb_module_set_private(module, ltdb);
+ talloc_steal(module, ltdb);
+
+ if (ltdb_cache_load(module) != 0) {
+ ldb_asprintf_errstring(ldb,
+ "Unable to load ltdb cache records of tdb '%s'", path);
+ talloc_free(module);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ *_module = module;
+ return LDB_SUCCESS;
+}
+
+int ldb_tdb_init(const char *version)
+{
+ LDB_MODULE_CHECK_VERSION(version);
+ return ldb_register_backend("tdb", ltdb_connect, false);
}
diff --git a/ldb_tdb/ldb_tdb.h b/ldb_tdb/ldb_tdb.h
index 2896c63..6788ab1 100644
--- a/ldb_tdb/ldb_tdb.h
+++ b/ldb_tdb/ldb_tdb.h
@@ -4,41 +4,10 @@
#include "tdb.h"
#include "ldb_module.h"
-struct ltdb_private;
-typedef int (*ldb_kv_traverse_fn)(struct ltdb_private *ltdb,
- struct ldb_val key, struct ldb_val data,
- void *ctx);
-
-struct kv_db_ops {
- int (*store)(struct ltdb_private *ltdb, struct ldb_val key, struct ldb_val data, int flags);
- int (*delete)(struct ltdb_private *ltdb, struct ldb_val key);
- int (*iterate)(struct ltdb_private *ltdb, ldb_kv_traverse_fn fn, void *ctx);
- int (*update_in_iterate)(struct ltdb_private *ltdb, struct ldb_val key,
- struct ldb_val key2, struct ldb_val data, void *ctx);
- int (*fetch_and_parse)(struct ltdb_private *ltdb, struct ldb_val key,
- int (*parser)(struct ldb_val key, struct ldb_val data,
- void *private_data),
- void *ctx);
- int (*lock_read)(struct ldb_module *);
- int (*unlock_read)(struct ldb_module *);
- int (*begin_write)(struct ltdb_private *);
- int (*prepare_write)(struct ltdb_private *);
- int (*abort_write)(struct ltdb_private *);
- int (*finish_write)(struct ltdb_private *);
- int (*error)(struct ltdb_private *ltdb);
- const char * (*errorstr)(struct ltdb_private *ltdb);
- const char * (*name)(struct ltdb_private *ltdb);
- bool (*has_changed)(struct ltdb_private *ltdb);
- bool (*transaction_active)(struct ltdb_private *ltdb);
-};
-
/* this private structure is used by the ltdb backend in the
ldb_context */
struct ltdb_private {
- const struct kv_db_ops *kv_ops;
- struct ldb_module *module;
TDB_CONTEXT *tdb;
- struct lmdb_private *lmdb_private;
unsigned int connect_flags;
unsigned long long sequence_number;
@@ -55,6 +24,7 @@ struct ltdb_private {
const char *GUID_index_dn_component;
} *cache;
+ int in_transaction;
bool check_base;
bool disallow_dn_filter;
@@ -72,23 +42,10 @@ struct ltdb_private {
const struct ldb_schema_syntax *GUID_index_syntax;
/*
- * Maximum index key length. If non zero keys longer than this length
- * will be truncated for non unique indexes. Keys for unique indexes
- * greater than this length will be rejected.
- */
- unsigned max_key_length;
-
- /*
* To allow testing that ensures the DB does not fall back
* to a full scan
*/
bool disable_full_db_scan;
-
- /*
- * The PID that opened this database so we don't work in a
- * fork()ed child.
- */
- pid_t pid;
};
struct ltdb_context {
@@ -109,13 +66,6 @@ struct ltdb_context {
int error;
};
-struct ltdb_reindex_context {
- struct ldb_module *module;
- int error;
- uint32_t count;
-};
-
-
/* special record types */
#define LTDB_INDEX "@INDEX"
#define LTDB_INDEXLIST "@INDEXLIST"
@@ -126,15 +76,6 @@ struct ltdb_reindex_context {
#define LTDB_IDXDN "@IDXDN"
#define LTDB_IDXGUID "@IDXGUID"
#define LTDB_IDX_DN_GUID "@IDX_DN_GUID"
-
-/*
- * This will be used to indicate when a new, yet to be developed
- * sub-database version of the indicies are in use, to ensure we do
- * not load future databases unintentionally.
- */
-
-#define LTDB_IDX_LMDB_SUBDB "@IDX_LMDB_SUBDB"
-
#define LTDB_BASEINFO "@BASEINFO"
#define LTDB_OPTIONS "@OPTIONS"
#define LTDB_ATTRIBUTES "@ATTRIBUTES"
@@ -210,6 +151,8 @@ int ltdb_filter_attrs(TALLOC_CTX *mem_ctx,
int ltdb_search(struct ltdb_context *ctx);
/* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */
+int ltdb_lock_read(struct ldb_module *module);
+int ltdb_unlock_read(struct ldb_module *module);
/*
* Determine if this key could hold a record. We allow the new GUID
* index, the old DN index and a possible future ID=
@@ -228,7 +171,6 @@ int ltdb_idx_to_key(struct ldb_module *module,
TALLOC_CTX *mem_ctx,
const struct ldb_val *idx_val,
TDB_DATA *key);
-TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn);
int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs);
int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg, struct ldb_request *req);
int ltdb_delete_noindex(struct ldb_module *module,
@@ -239,10 +181,3 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx,
const char *path, int hash_size, int tdb_flags,
int open_flags, mode_t mode,
struct ldb_context *ldb);
-int init_store(struct ltdb_private *ltdb, const char *name,
- struct ldb_context *ldb, const char *options[],
- struct ldb_module **_module);
-
-int ltdb_connect(struct ldb_context *ldb, const char *url,
- unsigned int flags, const char *options[],
- struct ldb_module **_module);
diff --git a/ldb_tdb/ldb_tdb_init.c b/ldb_tdb/ldb_tdb_init.c
deleted file mode 100644
index b18c98a..0000000
--- a/ldb_tdb/ldb_tdb_init.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- ldb database library
-
- Copyright (C) Andrew Tridgell 2004
- Copyright (C) Stefan Metzmacher 2004
- Copyright (C) Simo Sorce 2006-2008
- Copyright (C) Matthias Dieter Wallnöfer 2009-2010
-
- ** NOTE! The following LGPL license applies to the ldb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Name: ldb_tdb
- *
- * Component: ldb tdb backend
- *
- * Description: core functions for tdb backend
- *
- * Author: Andrew Tridgell
- * Author: Stefan Metzmacher
- *
- * Modifications:
- *
- * - description: make the module use asynchronous calls
- * date: Feb 2006
- * Author: Simo Sorce
- *
- * - description: make it possible to use event contexts
- * date: Jan 2008
- * Author: Simo Sorce
- *
- * - description: fix up memory leaks and small bugs
- * date: Oct 2009
- * Author: Matthias Dieter Wallnöfer
- */
-
-#include "ldb_tdb.h"
-#include "ldb_private.h"
-
-int ldb_tdb_init(const char *version)
-{
- LDB_MODULE_CHECK_VERSION(version);
- return ldb_register_backend("tdb", ltdb_connect, false);
-}
diff --git a/ldb_tdb/ldb_tdb_wrap.c b/ldb_tdb/ldb_tdb_wrap.c
index bc702a2..eb16809 100644
--- a/ldb_tdb/ldb_tdb_wrap.c
+++ b/ldb_tdb/ldb_tdb_wrap.c
@@ -74,7 +74,6 @@ struct ltdb_wrap {
struct tdb_context *tdb;
dev_t device;
ino_t inode;
- pid_t pid;
};
static struct ltdb_wrap *tdb_list;
@@ -106,25 +105,9 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx,
if (stat(path, &st) == 0) {
for (w=tdb_list;w;w=w->next) {
if (st.st_dev == w->device && st.st_ino == w->inode) {
- pid_t pid = getpid();
- int ret;
if (!talloc_reference(mem_ctx, w)) {
return NULL;
}
- if (w->pid != pid) {
- ret = tdb_reopen(w->tdb);
- if (ret != 0) {
- /*
- * Avoid use-after-free:
- * on fail the TDB
- * is closed!
- */
- DLIST_REMOVE(tdb_list,
- w);
- return NULL;
- }
- w->pid = pid;
- }
return w->tdb;
}
}
@@ -152,7 +135,6 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx,
w->device = st.st_dev;
w->inode = st.st_ino;
- w->pid = getpid();
talloc_set_destructor(w, ltdb_wrap_destructor);
diff --git a/lib/replace/replace.h b/lib/replace/replace.h
index 626d305..3304cda 100644
--- a/lib/replace/replace.h
+++ b/lib/replace/replace.h
@@ -924,15 +924,6 @@ void rep_setproctitle(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
#define setproctitle_init rep_setproctitle_init
void rep_setproctitle_init(int argc, char *argv[], char *envp[]);
#endif
-
-#ifndef FALL_THROUGH
-# ifdef HAVE_FALLTHROUGH_ATTRIBUTE
-# define FALL_THROUGH __attribute__ ((fallthrough))
-# else /* HAVE_FALLTHROUGH_ATTRIBUTE */
-# define FALL_THROUGH ((void)0)
-# endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
-#endif /* FALL_THROUGH */
-
bool nss_wrapper_enabled(void);
bool nss_wrapper_hosts_enabled(void);
bool socket_wrapper_enabled(void);
diff --git a/lib/replace/strptime.c b/lib/replace/strptime.c
index bbc7422..20e5d8c 100644
--- a/lib/replace/strptime.c
+++ b/lib/replace/strptime.c
@@ -462,8 +462,7 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
*decided = raw;
}
#endif
-
- FALL_THROUGH;
+ /* Fall through. */
case 'D':
/* Match standard day format. */
if (!recursive (HERE_D_FMT))
@@ -612,8 +611,7 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
*decided = raw;
}
#endif
-
- FALL_THROUGH;
+ /* Fall through. */
case 'T':
if (!recursive (HERE_T_FMT))
return NULL;
diff --git a/lib/replace/system/wscript_configure b/lib/replace/system/wscript_configure
index ecd9964..2035474 100644
--- a/lib/replace/system/wscript_configure
+++ b/lib/replace/system/wscript_configure
@@ -1,5 +1,8 @@
#!/usr/bin/env python
+conf.CHECK_HEADERS('sys/capability.h')
+conf.CHECK_FUNCS('getpwnam_r getpwuid_r getpwent_r')
+
# solaris varients of getXXent_r
conf.CHECK_C_PROTOTYPE('getpwent_r',
'struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)',
@@ -16,3 +19,8 @@ conf.CHECK_C_PROTOTYPE('getgrent_r',
'struct group *getgrent_r(struct group *src, char *buf, size_t buflen)',
define='SOLARIS_GETGRENT_R', headers='grp.h')
+conf.CHECK_FUNCS('getgrouplist')
+conf.CHECK_HEADERS('ctype.h locale.h langinfo.h')
+conf.CHECK_HEADERS('fnmatch.h locale.h langinfo.h')
+conf.CHECK_HEADERS('sys/ipc.h sys/mman.h sys/shm.h')
+conf.CHECK_HEADERS('termios.h termio.h sys/termio.h')
diff --git a/lib/replace/wscript b/lib/replace/wscript
index 541573b..0e04bf7 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -90,7 +90,8 @@ def configure(conf):
conf.CHECK_HEADERS('rpc/rpc.h rpc/nettype.h', lib='tirpc', together=True)
conf.SET_TARGET_TYPE('tirpc', 'SYSLIB')
if not conf.CONFIG_SET('HAVE_RPC_RPC_H'):
- Logs.warn('No rpc/rpc.h header found, tirpc or libntirpc missing?')
+ Logs.error('ERROR: No rpc/rpc.h header found, tirpc or libntirpc missing?')
+ sys.exit(1)
conf.SET_TARGET_TYPE('nsl', 'EMPTY')
conf.CHECK_HEADERS('rpc/rpc.h rpcsvc/yp_prot.h', lib='tirpc')
@@ -122,9 +123,6 @@ def configure(conf):
if conf.CHECK_CFLAGS('-Wno-unused-function'):
conf.define('HAVE_WNO_UNUSED_FUNCTION', '1')
- if conf.CHECK_CFLAGS('-Wno-strict-overflow'):
- conf.define('HAVE_WNO_STRICT_OVERFLOW', '1')
-
# Check for process set name support
conf.CHECK_CODE('''
#include <sys/prctl.h>
@@ -260,42 +258,6 @@ def configure(conf):
headers='stdint.h sys/atomic.h',
msg='Checking for atomic_add_32 compiler builtin')
- conf.CHECK_CODE('''
- #define FALL_THROUGH __attribute__((fallthrough))
-
- enum direction_e {
- UP = 0,
- DOWN,
- };
-
- int main(void) {
- enum direction_e key = UP;
- int i = 10;
- int j = 0;
-
- switch (key) {
- case UP:
- i = 5;
- FALL_THROUGH;
- case DOWN:
- j = i * 2;
- break;
- default:
- break;
- }
-
- if (j < i) {
- return 1;
- }
-
- return 0;
- }
- ''',
- 'HAVE_FALLTHROUGH_ATTRIBUTE',
- addmain=False,
- cflags='-Werror',
- msg='Checking for fallthrough attribute')
-
# these may be builtins, so we need the link=False strategy
conf.CHECK_FUNCS('strdup memmem printf memset memcpy memmove strcpy strncpy bzero', link=False)
diff --git a/lib/talloc/ABI/pytalloc-util-2.1.12.sigs b/lib/talloc/ABI/pytalloc-util-2.1.12.sigs
deleted file mode 100644
index 9d4d4d1..0000000
--- a/lib/talloc/ABI/pytalloc-util-2.1.12.sigs
+++ /dev/null
@@ -1,16 +0,0 @@
-_pytalloc_check_type: int (PyObject *, const char *)
-_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *)
-_pytalloc_get_ptr: void *(PyObject *)
-_pytalloc_get_type: void *(PyObject *, const char *)
-pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *)
-pytalloc_BaseObject_check: int (PyObject *)
-pytalloc_BaseObject_size: size_t (void)
-pytalloc_CObject_FromTallocPtr: PyObject *(void *)
-pytalloc_Check: int (PyObject *)
-pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *)
-pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *)
-pytalloc_GetBaseObjectType: PyTypeObject *(void)
-pytalloc_GetObjectType: PyTypeObject *(void)
-pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
-pytalloc_steal: PyObject *(PyTypeObject *, void *)
-pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
diff --git a/lib/talloc/ABI/pytalloc-util-2.1.13.sigs b/lib/talloc/ABI/pytalloc-util-2.1.13.sigs
deleted file mode 100644
index 9d4d4d1..0000000
--- a/lib/talloc/ABI/pytalloc-util-2.1.13.sigs
+++ /dev/null
@@ -1,16 +0,0 @@
-_pytalloc_check_type: int (PyObject *, const char *)
-_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *)
-_pytalloc_get_ptr: void *(PyObject *)
-_pytalloc_get_type: void *(PyObject *, const char *)
-pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *)
-pytalloc_BaseObject_check: int (PyObject *)
-pytalloc_BaseObject_size: size_t (void)
-pytalloc_CObject_FromTallocPtr: PyObject *(void *)
-pytalloc_Check: int (PyObject *)
-pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *)
-pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *)
-pytalloc_GetBaseObjectType: PyTypeObject *(void)
-pytalloc_GetObjectType: PyTypeObject *(void)
-pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
-pytalloc_steal: PyObject *(PyTypeObject *, void *)
-pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
diff --git a/lib/talloc/ABI/pytalloc-util.py3-2.1.12.sigs b/lib/talloc/ABI/pytalloc-util.py3-2.1.12.sigs
deleted file mode 100644
index 62f066f..0000000
--- a/lib/talloc/ABI/pytalloc-util.py3-2.1.12.sigs
+++ /dev/null
@@ -1,15 +0,0 @@
-_pytalloc_check_type: int (PyObject *, const char *)
-_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *)
-_pytalloc_get_ptr: void *(PyObject *)
-_pytalloc_get_type: void *(PyObject *, const char *)
-pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *)
-pytalloc_BaseObject_check: int (PyObject *)
-pytalloc_BaseObject_size: size_t (void)
-pytalloc_Check: int (PyObject *)
-pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *)
-pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *)
-pytalloc_GetBaseObjectType: PyTypeObject *(void)
-pytalloc_GetObjectType: PyTypeObject *(void)
-pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
-pytalloc_steal: PyObject *(PyTypeObject *, void *)
-pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
diff --git a/lib/talloc/ABI/pytalloc-util.py3-2.1.13.sigs b/lib/talloc/ABI/pytalloc-util.py3-2.1.13.sigs
deleted file mode 100644
index 62f066f..0000000
--- a/lib/talloc/ABI/pytalloc-util.py3-2.1.13.sigs
+++ /dev/null
@@ -1,15 +0,0 @@
-_pytalloc_check_type: int (PyObject *, const char *)
-_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *)
-_pytalloc_get_ptr: void *(PyObject *)
-_pytalloc_get_type: void *(PyObject *, const char *)
-pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *)
-pytalloc_BaseObject_check: int (PyObject *)
-pytalloc_BaseObject_size: size_t (void)
-pytalloc_Check: int (PyObject *)
-pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *)
-pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *)
-pytalloc_GetBaseObjectType: PyTypeObject *(void)
-pytalloc_GetObjectType: PyTypeObject *(void)
-pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
-pytalloc_steal: PyObject *(PyTypeObject *, void *)
-pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
diff --git a/lib/talloc/ABI/talloc-2.1.12.sigs b/lib/talloc/ABI/talloc-2.1.12.sigs
deleted file mode 100644
index 9969ce3..0000000
--- a/lib/talloc/ABI/talloc-2.1.12.sigs
+++ /dev/null
@@ -1,65 +0,0 @@
-_talloc: void *(const void *, size_t)
-_talloc_array: void *(const void *, size_t, unsigned int, const char *)
-_talloc_free: int (void *, const char *)
-_talloc_get_type_abort: void *(const void *, const char *, const char *)
-_talloc_memdup: void *(const void *, const void *, size_t, const char *)
-_talloc_move: void *(const void *, const void *)
-_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t)
-_talloc_realloc: void *(const void *, void *, size_t, const char *)
-_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *)
-_talloc_reference_loc: void *(const void *, const void *, const char *)
-_talloc_set_destructor: void (const void *, int (*)(void *))
-_talloc_steal_loc: void *(const void *, const void *, const char *)
-_talloc_zero: void *(const void *, size_t, const char *)
-_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *)
-talloc_asprintf: char *(const void *, const char *, ...)
-talloc_asprintf_append: char *(char *, const char *, ...)
-talloc_asprintf_append_buffer: char *(char *, const char *, ...)
-talloc_autofree_context: void *(void)
-talloc_check_name: void *(const void *, const char *)
-talloc_disable_null_tracking: void (void)
-talloc_enable_leak_report: void (void)
-talloc_enable_leak_report_full: void (void)
-talloc_enable_null_tracking: void (void)
-talloc_enable_null_tracking_no_autofree: void (void)
-talloc_find_parent_byname: void *(const void *, const char *)
-talloc_free_children: void (void *)
-talloc_get_name: const char *(const void *)
-talloc_get_size: size_t (const void *)
-talloc_increase_ref_count: int (const void *)
-talloc_init: void *(const char *, ...)
-talloc_is_parent: int (const void *, const void *)
-talloc_named: void *(const void *, size_t, const char *, ...)
-talloc_named_const: void *(const void *, size_t, const char *)
-talloc_parent: void *(const void *)
-talloc_parent_name: const char *(const void *)
-talloc_pool: void *(const void *, size_t)
-talloc_realloc_fn: void *(const void *, void *, size_t)
-talloc_reference_count: size_t (const void *)
-talloc_reparent: void *(const void *, const void *, const void *)
-talloc_report: void (const void *, FILE *)
-talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *)
-talloc_report_depth_file: void (const void *, int, int, FILE *)
-talloc_report_full: void (const void *, FILE *)
-talloc_set_abort_fn: void (void (*)(const char *))
-talloc_set_log_fn: void (void (*)(const char *))
-talloc_set_log_stderr: void (void)
-talloc_set_memlimit: int (const void *, size_t)
-talloc_set_name: const char *(const void *, const char *, ...)
-talloc_set_name_const: void (const void *, const char *)
-talloc_show_parents: void (const void *, FILE *)
-talloc_strdup: char *(const void *, const char *)
-talloc_strdup_append: char *(char *, const char *)
-talloc_strdup_append_buffer: char *(char *, const char *)
-talloc_strndup: char *(const void *, const char *, size_t)
-talloc_strndup_append: char *(char *, const char *, size_t)
-talloc_strndup_append_buffer: char *(char *, const char *, size_t)
-talloc_test_get_magic: int (void)
-talloc_total_blocks: size_t (const void *)
-talloc_total_size: size_t (const void *)
-talloc_unlink: int (const void *, void *)
-talloc_vasprintf: char *(const void *, const char *, va_list)
-talloc_vasprintf_append: char *(char *, const char *, va_list)
-talloc_vasprintf_append_buffer: char *(char *, const char *, va_list)
-talloc_version_major: int (void)
-talloc_version_minor: int (void)
diff --git a/lib/talloc/ABI/talloc-2.1.13.sigs b/lib/talloc/ABI/talloc-2.1.13.sigs
deleted file mode 100644
index 9969ce3..0000000
--- a/lib/talloc/ABI/talloc-2.1.13.sigs
+++ /dev/null
@@ -1,65 +0,0 @@
-_talloc: void *(const void *, size_t)
-_talloc_array: void *(const void *, size_t, unsigned int, const char *)
-_talloc_free: int (void *, const char *)
-_talloc_get_type_abort: void *(const void *, const char *, const char *)
-_talloc_memdup: void *(const void *, const void *, size_t, const char *)
-_talloc_move: void *(const void *, const void *)
-_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t)
-_talloc_realloc: void *(const void *, void *, size_t, const char *)
-_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *)
-_talloc_reference_loc: void *(const void *, const void *, const char *)
-_talloc_set_destructor: void (const void *, int (*)(void *))
-_talloc_steal_loc: void *(const void *, const void *, const char *)
-_talloc_zero: void *(const void *, size_t, const char *)
-_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *)
-talloc_asprintf: char *(const void *, const char *, ...)
-talloc_asprintf_append: char *(char *, const char *, ...)
-talloc_asprintf_append_buffer: char *(char *, const char *, ...)
-talloc_autofree_context: void *(void)
-talloc_check_name: void *(const void *, const char *)
-talloc_disable_null_tracking: void (void)
-talloc_enable_leak_report: void (void)
-talloc_enable_leak_report_full: void (void)
-talloc_enable_null_tracking: void (void)
-talloc_enable_null_tracking_no_autofree: void (void)
-talloc_find_parent_byname: void *(const void *, const char *)
-talloc_free_children: void (void *)
-talloc_get_name: const char *(const void *)
-talloc_get_size: size_t (const void *)
-talloc_increase_ref_count: int (const void *)
-talloc_init: void *(const char *, ...)
-talloc_is_parent: int (const void *, const void *)
-talloc_named: void *(const void *, size_t, const char *, ...)
-talloc_named_const: void *(const void *, size_t, const char *)
-talloc_parent: void *(const void *)
-talloc_parent_name: const char *(const void *)
-talloc_pool: void *(const void *, size_t)
-talloc_realloc_fn: void *(const void *, void *, size_t)
-talloc_reference_count: size_t (const void *)
-talloc_reparent: void *(const void *, const void *, const void *)
-talloc_report: void (const void *, FILE *)
-talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *)
-talloc_report_depth_file: void (const void *, int, int, FILE *)
-talloc_report_full: void (const void *, FILE *)
-talloc_set_abort_fn: void (void (*)(const char *))
-talloc_set_log_fn: void (void (*)(const char *))
-talloc_set_log_stderr: void (void)
-talloc_set_memlimit: int (const void *, size_t)
-talloc_set_name: const char *(const void *, const char *, ...)
-talloc_set_name_const: void (const void *, const char *)
-talloc_show_parents: void (const void *, FILE *)
-talloc_strdup: char *(const void *, const char *)
-talloc_strdup_append: char *(char *, const char *)
-talloc_strdup_append_buffer: char *(char *, const char *)
-talloc_strndup: char *(const void *, const char *, size_t)
-talloc_strndup_append: char *(char *, const char *, size_t)
-talloc_strndup_append_buffer: char *(char *, const char *, size_t)
-talloc_test_get_magic: int (void)
-talloc_total_blocks: size_t (const void *)
-talloc_total_size: size_t (const void *)
-talloc_unlink: int (const void *, void *)
-talloc_vasprintf: char *(const void *, const char *, va_list)
-talloc_vasprintf_append: char *(char *, const char *, va_list)
-talloc_vasprintf_append_buffer: char *(char *, const char *, va_list)
-talloc_version_major: int (void)
-talloc_version_minor: int (void)
diff --git a/lib/talloc/pytalloc.c b/lib/talloc/pytalloc.c
index 95dbb29..3532fdf 100644
--- a/lib/talloc/pytalloc.c
+++ b/lib/talloc/pytalloc.c
@@ -86,7 +86,7 @@ static PyObject *pytalloc_default_repr(PyObject *obj)
pytalloc_Object *talloc_obj = (pytalloc_Object *)obj;
PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj);
- return PyStr_FromFormat("<%s talloc object at %p>",
+ return PyStr_FromFormat("<%s talloc object at 0x%p>",
type->tp_name, talloc_obj->ptr);
}
diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index 54be634..cd159ef 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -121,12 +121,8 @@ static unsigned int talloc_magic = TALLOC_MAGIC_NON_RANDOM;
NULL
*/
static void *null_context;
-static bool talloc_report_null;
-static bool talloc_report_null_full;
static void *autofree_context;
-static void talloc_setup_atexit(void);
-
/* used to enable fill of memory on free, which can be useful for
* catching use after free errors when valgrind is too slow
*/
@@ -430,33 +426,6 @@ void talloc_lib_init(void)
#warning "No __attribute__((constructor)) support found on this platform, additional talloc security measures not available"
#endif
-static void talloc_lib_atexit(void)
-{
- TALLOC_FREE(autofree_context);
-
- if (talloc_total_size(null_context) == 0) {
- return;
- }
-
- if (talloc_report_null_full) {
- talloc_report_full(null_context, stderr);
- } else if (talloc_report_null) {
- talloc_report(null_context, stderr);
- }
-}
-
-static void talloc_setup_atexit(void)
-{
- static bool done;
-
- if (done) {
- return;
- }
-
- atexit(talloc_lib_atexit);
- done = true;
-}
-
static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
static void talloc_log(const char *fmt, ...)
{
@@ -2326,6 +2295,26 @@ _PUBLIC_ void talloc_report(const void *ptr, FILE *f)
}
/*
+ report on any memory hanging off the null context
+*/
+static void talloc_report_null(void)
+{
+ if (talloc_total_size(null_context) != 0) {
+ talloc_report(null_context, stderr);
+ }
+}
+
+/*
+ report on any memory hanging off the null context
+*/
+static void talloc_report_null_full(void)
+{
+ if (talloc_total_size(null_context) != 0) {
+ talloc_report_full(null_context, stderr);
+ }
+}
+
+/*
enable tracking of the NULL context
*/
_PUBLIC_ void talloc_enable_null_tracking(void)
@@ -2380,8 +2369,7 @@ _PUBLIC_ void talloc_disable_null_tracking(void)
_PUBLIC_ void talloc_enable_leak_report(void)
{
talloc_enable_null_tracking();
- talloc_report_null = true;
- talloc_setup_atexit();
+ atexit(talloc_report_null);
}
/*
@@ -2390,8 +2378,7 @@ _PUBLIC_ void talloc_enable_leak_report(void)
_PUBLIC_ void talloc_enable_leak_report_full(void)
{
talloc_enable_null_tracking();
- talloc_report_null_full = true;
- talloc_setup_atexit();
+ atexit(talloc_report_null_full);
}
/*
@@ -2567,8 +2554,7 @@ static struct talloc_chunk *_vasprintf_tc(const void *t,
const char *fmt,
va_list ap)
{
- int vlen;
- size_t len;
+ int len;
char *ret;
va_list ap2;
struct talloc_chunk *tc;
@@ -2576,13 +2562,9 @@ static struct talloc_chunk *_vasprintf_tc(const void *t,
/* this call looks strange, but it makes it work on older solaris boxes */
va_copy(ap2, ap);
- vlen = vsnprintf(buf, sizeof(buf), fmt, ap2);
+ len = vsnprintf(buf, sizeof(buf), fmt, ap2);
va_end(ap2);
- if (unlikely(vlen < 0)) {
- return NULL;
- }
- len = vlen;
- if (unlikely(len + 1 < len)) {
+ if (unlikely(len < 0)) {
return NULL;
}
@@ -2778,6 +2760,11 @@ static int talloc_autofree_destructor(void *ptr)
return 0;
}
+static void talloc_autofree(void)
+{
+ talloc_free(autofree_context);
+}
+
/*
return a context which will be auto-freed on exit
this is useful for reducing the noise in leak reports
@@ -2787,7 +2774,7 @@ _PUBLIC_ void *talloc_autofree_context(void)
if (autofree_context == NULL) {
autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
talloc_set_destructor(autofree_context, talloc_autofree_destructor);
- talloc_setup_atexit();
+ atexit(talloc_autofree);
}
return autofree_context;
}
diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h
index 7372df1..618430a 100644
--- a/lib/talloc/talloc.h
+++ b/lib/talloc/talloc.h
@@ -1226,7 +1226,7 @@ size_t talloc_array_length(const void *ctx);
*
* @code
* ptr = talloc_array(ctx, type, count);
- * if (ptr) memset(ptr, 0, sizeof(type) * count);
+ * if (ptr) memset(ptr, sizeof(type) * count);
* @endcode
*/
void *talloc_zero_array(const void *ctx, #type, unsigned count);
@@ -1898,8 +1898,8 @@ void talloc_set_log_stderr(void);
* This affects all children of this context and constrain any
* allocation in the hierarchy to never exceed the limit set.
* The limit can be removed by setting 0 (unlimited) as the
- * max_size by calling the function again on the same context.
- * Memory limits can also be nested, meaning a child can have
+ * max_size by calling the funciton again on the sam context.
+ * Memory limits can also be nested, meaning a hild can have
* a stricter memory limit than a parent.
* Memory limits are enforced only at memory allocation time.
* Stealing a context into a 'limited' hierarchy properly
diff --git a/lib/talloc/wscript b/lib/talloc/wscript
index 1b31672..0afa162 100644
--- a/lib/talloc/wscript
+++ b/lib/talloc/wscript
@@ -1,7 +1,7 @@
#!/usr/bin/env python
APPNAME = 'talloc'
-VERSION = '2.1.13'
+VERSION = '2.1.11'
blddir = 'bin'
@@ -165,7 +165,7 @@ def build(bld):
bld.SAMBA_PYTHON('test_pytalloc',
'test_pytalloc.c',
- deps=name,
+ deps='pytalloc',
enabled=bld.PYTHON_BUILD_IS_ENABLED(),
realname='_test_pytalloc.so',
install=False)
diff --git a/lib/tdb/common/check.c b/lib/tdb/common/check.c
index 3a5c8b8..e632af5 100644
--- a/lib/tdb/common/check.c
+++ b/lib/tdb/common/check.c
@@ -242,27 +242,12 @@ static bool tdb_check_used_record(struct tdb_context *tdb,
void *private_data)
{
TDB_DATA key, data;
- tdb_len_t len;
if (!tdb_check_record(tdb, off, rec))
return false;
/* key + data + tailer must fit in record */
- len = rec->key_len;
- len += rec->data_len;
- if (len < rec->data_len) {
- /* overflow */
- TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record lengths overflow\n"));
- return false;
- }
- len += sizeof(tdb_off_t);
- if (len < sizeof(tdb_off_t)) {
- /* overflow */
- TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record lengths overflow\n"));
- return false;
- }
-
- if (len > rec->rec_len) {
+ if (rec->key_len + rec->data_len + sizeof(tdb_off_t) > rec->rec_len) {
TDB_LOG((tdb, TDB_DEBUG_ERROR,
"Record offset %u too short for contents\n", off));
return false;
diff --git a/lib/tdb/common/hash.c b/lib/tdb/common/hash.c
index 4de7ba9..1eed722 100644
--- a/lib/tdb/common/hash.c
+++ b/lib/tdb/common/hash.c
@@ -232,16 +232,16 @@ static uint32_t hashlittle( const void *key, size_t length )
switch(length)
{
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
- case 11: c+=((uint32_t)k8[10])<<16; FALL_THROUGH;
- case 10: c+=((uint32_t)k8[9])<<8; FALL_THROUGH;
- case 9 : c+=k8[8]; FALL_THROUGH;
+ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
+ case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
+ case 9 : c+=k8[8]; /* fall through */
case 8 : b+=k[1]; a+=k[0]; break;
- case 7 : b+=((uint32_t)k8[6])<<16; FALL_THROUGH;
- case 6 : b+=((uint32_t)k8[5])<<8; FALL_THROUGH;
- case 5 : b+=k8[4]; FALL_THROUGH;
+ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
+ case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
+ case 5 : b+=k8[4]; /* fall through */
case 4 : a+=k[0]; break;
- case 3 : a+=((uint32_t)k8[2])<<16; FALL_THROUGH;
- case 2 : a+=((uint32_t)k8[1])<<8; FALL_THROUGH;
+ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
+ case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
case 1 : a+=k8[0]; break;
case 0 : return c;
}
@@ -268,23 +268,23 @@ static uint32_t hashlittle( const void *key, size_t length )
b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
- case 11: c+=((uint32_t)k8[10])<<16; FALL_THROUGH;
+ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
case 10: c+=k[4];
b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
- case 9 : c+=k8[8]; FALL_THROUGH;
+ case 9 : c+=k8[8]; /* fall through */
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
- case 7 : b+=((uint32_t)k8[6])<<16; FALL_THROUGH;
+ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
case 6 : b+=k[2];
a+=k[0]+(((uint32_t)k[1])<<16);
break;
- case 5 : b+=k8[4]; FALL_THROUGH;
+ case 5 : b+=k8[4]; /* fall through */
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
break;
- case 3 : a+=((uint32_t)k8[2])<<16; FALL_THROUGH;
+ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
case 2 : a+=k[0];
break;
case 1 : a+=k8[0];
@@ -316,19 +316,19 @@ static uint32_t hashlittle( const void *key, size_t length )
}
/*-------------------------------- last block: affect all 32 bits of (c) */
- switch(length)
+ switch(length) /* all the case statements fall through */
{
- case 12: c+=((uint32_t)k[11])<<24; FALL_THROUGH;
- case 11: c+=((uint32_t)k[10])<<16; FALL_THROUGH;
- case 10: c+=((uint32_t)k[9])<<8; FALL_THROUGH;
- case 9 : c+=k[8]; FALL_THROUGH;
- case 8 : b+=((uint32_t)k[7])<<24; FALL_THROUGH;
- case 7 : b+=((uint32_t)k[6])<<16; FALL_THROUGH;
- case 6 : b+=((uint32_t)k[5])<<8; FALL_THROUGH;
- case 5 : b+=k[4]; FALL_THROUGH;
- case 4 : a+=((uint32_t)k[3])<<24; FALL_THROUGH;
- case 3 : a+=((uint32_t)k[2])<<16; FALL_THROUGH;
- case 2 : a+=((uint32_t)k[1])<<8; FALL_THROUGH;
+ case 12: c+=((uint32_t)k[11])<<24;
+ case 11: c+=((uint32_t)k[10])<<16;
+ case 10: c+=((uint32_t)k[9])<<8;
+ case 9 : c+=k[8];
+ case 8 : b+=((uint32_t)k[7])<<24;
+ case 7 : b+=((uint32_t)k[6])<<16;
+ case 6 : b+=((uint32_t)k[5])<<8;
+ case 5 : b+=k[4];
+ case 4 : a+=((uint32_t)k[3])<<24;
+ case 3 : a+=((uint32_t)k[2])<<16;
+ case 2 : a+=((uint32_t)k[1])<<8;
case 1 : a+=k[0];
break;
case 0 : return c;
diff --git a/lib/tdb/common/io.c b/lib/tdb/common/io.c
index 94b3163..15ba5b7 100644
--- a/lib/tdb/common/io.c
+++ b/lib/tdb/common/io.c
@@ -733,9 +733,6 @@ int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key,
/* read/write a record */
int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec)
{
- int ret;
- tdb_len_t overall_len;
-
if (tdb->methods->tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1)
return -1;
if (TDB_BAD_MAGIC(rec)) {
@@ -744,31 +741,6 @@ int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *r
TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_rec_read bad magic 0x%x at offset=%u\n", rec->magic, offset));
return -1;
}
-
- overall_len = rec->key_len + rec->data_len;
- if (overall_len < rec->data_len) {
- /* overflow */
- return -1;
- }
-
- if (overall_len > rec->rec_len) {
- /* invalid record */
- return -1;
- }
-
- ret = tdb->methods->tdb_oob(tdb, offset, rec->key_len, 1);
- if (ret == -1) {
- return -1;
- }
- ret = tdb->methods->tdb_oob(tdb, offset, rec->data_len, 1);
- if (ret == -1) {
- return -1;
- }
- ret = tdb->methods->tdb_oob(tdb, offset, rec->rec_len, 1);
- if (ret == -1) {
- return -1;
- }
-
return tdb->methods->tdb_oob(tdb, rec->next, sizeof(*rec), 0);
}
diff --git a/lib/tdb/common/open.c b/lib/tdb/common/open.c
index 8baa7e4..cfb476d 100644
--- a/lib/tdb/common/open.c
+++ b/lib/tdb/common/open.c
@@ -687,21 +687,6 @@ _PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int td
}
}
- if (tdb->hash_size > UINT32_MAX/4) {
- TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
- "hash size %"PRIu32" too large\n", tdb->hash_size));
- errno = EINVAL;
- goto fail;
- }
-
- ret = tdb->methods->tdb_oob(tdb, FREELIST_TOP, 4*tdb->hash_size, 1);
- if (ret == -1) {
- TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
- "hash size %"PRIu32" does not fit\n", tdb->hash_size));
- errno = EINVAL;
- goto fail;
- }
-
if (locked) {
if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) {
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
diff --git a/lib/tdb/common/summary.c b/lib/tdb/common/summary.c
index c9b5bc4..d786132 100644
--- a/lib/tdb/common/summary.c
+++ b/lib/tdb/common/summary.c
@@ -151,8 +151,7 @@ _PUBLIC_ char *tdb_summary(struct tdb_context *tdb)
rec.rec_len = tdb_dead_space(tdb, off)
- sizeof(rec);
}
-
- FALL_THROUGH;
+ /* Fall through */
case TDB_DEAD_MAGIC:
tally_add(&dead, rec.rec_len);
break;
diff --git a/lib/tdb/common/transaction.c b/lib/tdb/common/transaction.c
index 73d02b6..7d281fc 100644
--- a/lib/tdb/common/transaction.c
+++ b/lib/tdb/common/transaction.c
@@ -592,8 +592,7 @@ static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t
static int _tdb_transaction_cancel(struct tdb_context *tdb)
{
- uint32_t i;
- int ret = 0;
+ int i, ret = 0;
if (tdb->transaction == NULL) {
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n"));
@@ -655,7 +654,7 @@ _PUBLIC_ int tdb_transaction_cancel(struct tdb_context *tdb)
static bool tdb_recovery_size(struct tdb_context *tdb, tdb_len_t *result)
{
tdb_len_t recovery_size = 0;
- uint32_t i;
+ int i;
recovery_size = sizeof(uint32_t);
for (i=0;i<tdb->transaction->num_blocks;i++) {
@@ -690,8 +689,6 @@ int tdb_recovery_area(struct tdb_context *tdb,
tdb_off_t *recovery_offset,
struct tdb_record *rec)
{
- int ret;
-
if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, recovery_offset) == -1) {
return -1;
}
@@ -712,13 +709,6 @@ int tdb_recovery_area(struct tdb_context *tdb,
*recovery_offset = 0;
rec->rec_len = 0;
}
-
- ret = methods->tdb_oob(tdb, *recovery_offset, rec->rec_len, 1);
- if (ret == -1) {
- *recovery_offset = 0;
- rec->rec_len = 0;
- }
-
return 0;
}
@@ -844,7 +834,7 @@ static int transaction_setup_recovery(struct tdb_context *tdb,
tdb_off_t recovery_offset, recovery_max_size;
tdb_off_t old_map_size = tdb->transaction->old_map_size;
uint32_t magic, tailer;
- uint32_t i;
+ int i;
/*
check that the recovery area has enough space
@@ -854,12 +844,13 @@ static int transaction_setup_recovery(struct tdb_context *tdb,
return -1;
}
- rec = malloc(recovery_size + sizeof(*rec));
- if (rec == NULL) {
+ data = (unsigned char *)malloc(recovery_size + sizeof(*rec));
+ if (data == NULL) {
tdb->ecode = TDB_ERR_OOM;
return -1;
}
+ rec = (struct tdb_record *)data;
memset(rec, 0, sizeof(*rec));
rec->magic = TDB_RECOVERY_INVALID_MAGIC;
@@ -868,8 +859,6 @@ static int transaction_setup_recovery(struct tdb_context *tdb,
rec->key_len = old_map_size;
CONVERT(*rec);
- data = (unsigned char *)rec;
-
/* build the recovery data into a single blob to allow us to do a single
large write, which should be more efficient */
p = data + sizeof(*rec);
@@ -1107,7 +1096,7 @@ static bool repack_worthwhile(struct tdb_context *tdb)
_PUBLIC_ int tdb_transaction_commit(struct tdb_context *tdb)
{
const struct tdb_methods *methods;
- uint32_t i;
+ int i;
bool need_repack = false;
if (tdb->transaction == NULL) {
diff --git a/lib/tdb/common/traverse.c b/lib/tdb/common/traverse.c
index 7a1d567..9b83379 100644
--- a/lib/tdb/common/traverse.c
+++ b/lib/tdb/common/traverse.c
@@ -166,16 +166,9 @@ static int tdb_traverse_internal(struct tdb_context *tdb,
/* tdb_next_lock places locks on the record returned, and its chain */
while ((off = tdb_next_lock(tdb, tl, &rec)) != 0) {
- tdb_len_t full_len;
+ tdb_len_t full_len = rec.key_len + rec.data_len;
int nread;
- if (off == TDB_NEXT_LOCK_ERR) {
- ret = -1;
- goto out;
- }
-
- full_len = rec.key_len + rec.data_len;
-
if (full_len > recbuf_len) {
recbuf_len = full_len;
@@ -202,6 +195,10 @@ static int tdb_traverse_internal(struct tdb_context *tdb,
}
}
+ if (off == TDB_NEXT_LOCK_ERR) {
+ ret = -1;
+ goto out;
+ }
count++;
/* now read the full record */
nread = tdb->methods->tdb_read(tdb, tl->off + sizeof(rec),
diff --git a/lib/tdb/python/tdbdump.py b/lib/tdb/python/tdbdump.py
index 08769ea..01859eb 100644
--- a/lib/tdb/python/tdbdump.py
+++ b/lib/tdb/python/tdbdump.py
@@ -1,13 +1,12 @@
#!/usr/bin/env python
# Trivial reimplementation of tdbdump in Python
-from __future__ import print_function
import tdb, sys
if len(sys.argv) < 2:
- print("Usage: tdbdump.py <tdb-file>")
+ print "Usage: tdbdump.py <tdb-file>"
sys.exit(1)
db = tdb.Tdb(sys.argv[1])
-for (k, v) in db.items():
- print("{\nkey(%d) = %r\ndata(%d) = %r\n}" % (len(k), k, len(v), v))
+for (k, v) in db.iteritems():
+ print "{\nkey(%d) = %r\ndata(%d) = %r\n}" % (len(k), k, len(v), v)
diff --git a/lib/tdb/tools/tdbdump.c b/lib/tdb/tools/tdbdump.c
index 2c68970..8cf3146 100644
--- a/lib/tdb/tools/tdbdump.c
+++ b/lib/tdb/tools/tdbdump.c
@@ -41,10 +41,10 @@ static void print_data(TDB_DATA d)
static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
printf("{\n");
- printf("key(%zu) = \"", key.dsize);
+ printf("key(%d) = \"", (int)key.dsize);
print_data(key);
printf("\"\n");
- printf("data(%zu) = \"", dbuf.dsize);
+ printf("data(%d) = \"", (int)dbuf.dsize);
print_data(dbuf);
printf("\"\n");
printf("}\n");
diff --git a/lib/tdb/tools/tdbtool.c b/lib/tdb/tools/tdbtool.c
index 3e9d154..e3535b9 100644
--- a/lib/tdb/tools/tdbtool.c
+++ b/lib/tdb/tools/tdbtool.c
@@ -647,6 +647,12 @@ static char *tdb_getline(const char *prompt)
return p?thisline:NULL;
}
+static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
+ void *state)
+{
+ return tdb_delete(the_tdb, key);
+}
+
static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey)
{
TDB_DATA dbuf;
@@ -752,7 +758,7 @@ static int do_command(void)
return 0;
case CMD_ERASE:
bIterate = 0;
- tdb_wipe_all(tdb);
+ tdb_traverse(tdb, do_delete_fn, NULL);
return 0;
case CMD_DUMP:
bIterate = 0;
@@ -924,13 +930,10 @@ int main(int argc, char *argv[])
break;
case 5:
arg2 = tdb_convert_string(argv[4],&arg2len);
- FALL_THROUGH;
case 4:
arg1 = tdb_convert_string(argv[3],&arg1len);
- FALL_THROUGH;
case 3:
cmdname = argv[2];
- FALL_THROUGH;
default:
do_command();
break;
diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c
index 369ec6e..10d8a22 100644
--- a/lib/tevent/pytevent.c
+++ b/lib/tevent/pytevent.c
@@ -188,7 +188,7 @@ static PyObject *py_register_backend(PyObject *self, PyObject *args)
return NULL;
}
- if (!(PyStr_Check(name) || PyUnicode_Check(name))) {
+ if (!PyStr_Check(name)) {
PyErr_SetNone(PyExc_TypeError);
Py_DECREF(name);
return NULL;
diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index 63abbf2..e508452 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -375,7 +375,6 @@ static bool test_event_fd1(struct torture_context *tctx,
const void *test_data)
{
struct test_event_fd1_state state;
- int ret;
ZERO_STRUCT(state);
state.tctx = tctx;
@@ -416,9 +415,7 @@ static bool test_event_fd1(struct torture_context *tctx,
*/
state.sock[0] = -1;
state.sock[1] = -1;
-
- ret = socketpair(AF_UNIX, SOCK_STREAM, 0, state.sock);
- torture_assert(tctx, ret == 0, "socketpair() failed");
+ socketpair(AF_UNIX, SOCK_STREAM, 0, state.sock);
state.te = tevent_add_timer(state.ev, state.ev,
timeval_current_ofs(0,1000),
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 3ccac6a..7bb9c61 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -1026,8 +1026,7 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
#endif
/**
- * @brief Set a timeout for an async request. On failure, "req" is already
- * set to state TEVENT_REQ_NO_MEMORY.
+ * @brief Set a timeout for an async request.
*
* @param[in] req The request to set the timeout for.
*
diff --git a/modules/paged_results.c b/modules/paged_results.c
index ecb2227..de014a3 100644
--- a/modules/paged_results.c
+++ b/modules/paged_results.c
@@ -35,8 +35,6 @@
#include "replace.h"
#include "system/filesys.h"
#include "system/time.h"
-#include "dlinklist.h"
-#include <assert.h>
#include "ldb_module.h"
struct message_store {
@@ -50,13 +48,14 @@ struct message_store {
struct private_data;
struct results_store {
- struct results_store *prev, *next;
struct private_data *priv;
char *cookie;
time_t timestamp;
+ struct results_store *next;
+
struct message_store *first;
struct message_store *last;
int num_entries;
@@ -69,7 +68,6 @@ struct results_store {
struct private_data {
uint32_t next_free_id;
- size_t num_stores;
struct results_store *store;
};
@@ -77,12 +75,22 @@ struct private_data {
static int store_destructor(struct results_store *del)
{
struct private_data *priv = del->priv;
- DLIST_REMOVE(priv->store, del);
+ struct results_store *loop;
+
+ if (priv->store == del) {
+ priv->store = del->next;
+ return 0;
+ }
- assert(priv->num_stores > 0);
- priv->num_stores -= 1;
+ for (loop = priv->store; loop; loop = loop->next) {
+ if (loop->next == del) {
+ loop->next = del->next;
+ return 0;
+ }
+ }
- return 0;
+ /* is not in list ? */
+ return -1;
}
static struct results_store *new_store(struct private_data *priv)
@@ -112,23 +120,11 @@ static struct results_store *new_store(struct private_data *priv)
newr->first_ref = NULL;
newr->controls = NULL;
- DLIST_ADD(priv->store, newr);
-
- assert(priv->num_stores < SIZE_MAX);
- priv->num_stores += 1;
+ newr->next = priv->store;
+ priv->store = newr;
talloc_set_destructor(newr, store_destructor);
- if (priv->num_stores > 10) {
- struct results_store *last;
- /*
- * 10 is the default for MaxResultSetsPerConn --
- * possibly need to parameterize it.
- */
- last = DLIST_TAIL(priv->store);
- TALLOC_FREE(last);
- }
-
return newr;
}
@@ -385,8 +381,6 @@ static int paged_search(struct ldb_module *module, struct ldb_request *req)
return LDB_ERR_UNWILLING_TO_PERFORM;
}
- DLIST_PROMOTE(private_data->store, current);
-
ac->store = current;
/* check if it is an abandon */
@@ -418,7 +412,6 @@ static int paged_request_init(struct ldb_module *module)
}
data->next_free_id = 1;
- data->num_stores = 0;
data->store = NULL;
ldb_module_set_private(module, data);
diff --git a/pyldb.c b/pyldb.c
index 110ec8e..04b3f1b 100644
--- a/pyldb.c
+++ b/pyldb.c
@@ -1078,7 +1078,7 @@ static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
const char *str = NULL;
Py_ssize_t size;
PyObject *item = PyList_GetItem(list, i);
- if (!(PyStr_Check(item) || PyUnicode_Check(item))) {
+ if (!PyStr_Check(item)) {
PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
talloc_free(ret);
return NULL;
@@ -1154,7 +1154,7 @@ static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs
static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
{
- char *url = NULL;
+ char *url;
unsigned int flags = 0;
PyObject *py_options = Py_None;
int ret;
@@ -2861,7 +2861,7 @@ static struct ldb_message_element *PyObject_AsMessageElement(
me->name = talloc_strdup(me, attr_name);
me->flags = flags;
- if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
+ if (PyBytes_Check(set_obj) || PyStr_Check(set_obj)) {
me->num_values = 1;
me->values = talloc_array(me, struct ldb_val, me->num_values);
if (PyBytes_Check(set_obj)) {
@@ -2897,7 +2897,7 @@ static struct ldb_message_element *PyObject_AsMessageElement(
return NULL;
}
msg = _msg;
- } else if (PyUnicode_Check(obj)) {
+ } else if (PyStr_Check(obj)) {
msg = PyStr_AsUTF8AndSize(obj, &size);
if (msg == NULL) {
talloc_free(me);
@@ -3069,7 +3069,7 @@ static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyOb
if (py_elements != NULL) {
Py_ssize_t i;
- if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
+ if (PyBytes_Check(py_elements) || PyStr_Check(py_elements)) {
char *_msg = NULL;
el->num_values = 1;
el->values = talloc_array(el, struct ldb_val, 1);
@@ -3110,7 +3110,7 @@ static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyOb
char *_msg = NULL;
result = PyBytes_AsStringAndSize(item, &_msg, &size);
msg = _msg;
- } else if (PyUnicode_Check(item)) {
+ } else if (PyStr_Check(item)) {
msg = PyStr_AsUTF8AndSize(item, &size);
result = (msg == NULL) ? -1 : 0;
} else {
@@ -4226,10 +4226,6 @@ static PyObject* module_init(void)
ADD_LDB_INT(FLG_NOSYNC);
ADD_LDB_INT(FLG_RECONNECT);
ADD_LDB_INT(FLG_NOMMAP);
- ADD_LDB_INT(FLG_SHOW_BINARY);
- ADD_LDB_INT(FLG_ENABLE_TRACING);
- ADD_LDB_INT(FLG_DONT_CREATE_DB);
-
/* Historical misspelling */
PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
diff --git a/pyldb_util.c b/pyldb_util.c
index 46ee403..3bda1db 100644
--- a/pyldb_util.c
+++ b/pyldb_util.c
@@ -70,7 +70,7 @@ bool pyldb_Object_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
struct ldb_dn *odn;
PyTypeObject *PyLdb_Dn_Type;
- if (ldb_ctx != NULL && (PyStr_Check(object) || PyUnicode_Check(object))) {
+ if (ldb_ctx != NULL && PyStr_Check(object)) {
odn = ldb_dn_new(mem_ctx, ldb_ctx, PyStr_AsUTF8(object));
*dn = odn;
return true;
diff --git a/tests/ldb_kv_ops_test.c b/tests/ldb_kv_ops_test.c
deleted file mode 100644
index 30ce019..0000000
--- a/tests/ldb_kv_ops_test.c
+++ /dev/null
@@ -1,1576 +0,0 @@
-/*
- * Tests exercising the ldb key value operations.
- *
- * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/*
- * from cmocka.c:
- * These headers or their equivalents should be included prior to
- * including
- * this header file.
- *
- * #include <stdarg.h>
- * #include <stddef.h>
- * #include <setjmp.h>
- *
- * This allows test applications to use custom definitions of C standard
- * library functions and types.
- *
- */
-
-/*
- * A KV module is expected to have the following behaviour
- *
- * - A transaction must be open to perform any read, write or delete operation
- * - Writes and Deletes should not be visible until a transaction is commited
- * - Nested transactions are not permitted
- * - transactions can be rolled back and commited.
- * - supports iteration over all records in the database
- * - supports the update_in_iterate operation allowing entries to be
- * re-keyed.
- */
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <errno.h>
-#include <unistd.h>
-#include <talloc.h>
-#include <tevent.h>
-#include <ldb.h>
-#include <ldb_module.h>
-#include <ldb_private.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <sys/wait.h>
-
-#include "ldb_tdb/ldb_tdb.h"
-
-
-#define DEFAULT_BE "tdb"
-
-#ifndef TEST_BE
-#define TEST_BE DEFAULT_BE
-#endif /* TEST_BE */
-
-#define NUM_RECS 1024
-
-
-struct test_ctx {
- struct tevent_context *ev;
- struct ldb_context *ldb;
-
- const char *dbfile;
- const char *lockfile; /* lockfile is separate */
-
- const char *dbpath;
-};
-
-static void unlink_old_db(struct test_ctx *test_ctx)
-{
- int ret;
-
- errno = 0;
- ret = unlink(test_ctx->lockfile);
- if (ret == -1 && errno != ENOENT) {
- fail();
- }
-
- errno = 0;
- ret = unlink(test_ctx->dbfile);
- if (ret == -1 && errno != ENOENT) {
- fail();
- }
-}
-
-static int noconn_setup(void **state)
-{
- struct test_ctx *test_ctx;
-
- test_ctx = talloc_zero(NULL, struct test_ctx);
- assert_non_null(test_ctx);
-
- test_ctx->ev = tevent_context_init(test_ctx);
- assert_non_null(test_ctx->ev);
-
- test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
- assert_non_null(test_ctx->ldb);
-
- test_ctx->dbfile = talloc_strdup(test_ctx, "kvopstest.ldb");
- assert_non_null(test_ctx->dbfile);
-
- test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
- test_ctx->dbfile);
- assert_non_null(test_ctx->lockfile);
-
- test_ctx->dbpath = talloc_asprintf(test_ctx,
- TEST_BE"://%s", test_ctx->dbfile);
- assert_non_null(test_ctx->dbpath);
-
- unlink_old_db(test_ctx);
- *state = test_ctx;
- return 0;
-}
-
-static int noconn_teardown(void **state)
-{
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
-
- unlink_old_db(test_ctx);
- talloc_free(test_ctx);
- return 0;
-}
-
-static int setup(void **state)
-{
- struct test_ctx *test_ctx;
- int ret;
- struct ldb_ldif *ldif;
- const char *index_ldif = \
- "dn: @INDEXLIST\n"
- "@IDXGUID: objectUUID\n"
- "@IDX_DN_GUID: GUID\n"
- "\n";
-
- noconn_setup((void **) &test_ctx);
-
- ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
-
- while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) {
- ret = ldb_add(test_ctx->ldb, ldif->msg);
- assert_int_equal(ret, LDB_SUCCESS);
- }
- *state = test_ctx;
- return 0;
-}
-
-static int teardown(void **state)
-{
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- noconn_teardown((void **) &test_ctx);
- return 0;
-}
-
-static struct ltdb_private *get_ltdb(struct ldb_context *ldb)
-{
- void *data = NULL;
- struct ltdb_private *ltdb = NULL;
-
- data = ldb_module_get_private(ldb->modules);
- assert_non_null(data);
-
- ltdb = talloc_get_type(data, struct ltdb_private);
- assert_non_null(ltdb);
-
- return ltdb;
-}
-
-static int parse(struct ldb_val key,
- struct ldb_val data,
- void *private_data)
-{
- struct ldb_val* read = private_data;
-
- /* Yes, we essentially leak this. That is OK */
- read->data = talloc_size(talloc_autofree_context(),
- data.length);
- assert_non_null(read->data);
-
- memcpy(read->data, data.data, data.length);
- read->length = data.length;
- return LDB_SUCCESS;
-}
-
-/*
- * Test that data can be written to the kv store and be read back.
- */
-static void test_add_get(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- uint8_t key_val[] = "TheKey";
- struct ldb_val key = {
- .data = key_val,
- .length = sizeof(key_val)
- };
-
- uint8_t value[] = "The record contents";
- struct ldb_val data = {
- .data = value,
- .length = sizeof(value)
- };
-
- struct ldb_val read;
-
- int flags = 0;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- /*
- * Begin a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Write the record
- */
- ret = ltdb->kv_ops->store(ltdb, key, data, flags);
- assert_int_equal(ret, 0);
-
- /*
- * Commit the transaction
- */
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * And now read it back
- */
- ret = ltdb->kv_ops->lock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
-
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, 0);
-
- assert_int_equal(sizeof(value), read.length);
- assert_memory_equal(value, read.data, sizeof(value));
-
- ret = ltdb->kv_ops->unlock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
- talloc_free(tmp_ctx);
-}
-
-/*
- * Test that attempts to read data without a read transaction fail.
- */
-static void test_read_outside_transaction(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- uint8_t key_val[] = "TheKey";
- struct ldb_val key = {
- .data = key_val,
- .length = sizeof(key_val)
- };
-
- uint8_t value[] = "The record contents";
- struct ldb_val data = {
- .data = value,
- .length = sizeof(value)
- };
-
- struct ldb_val read;
-
- int flags = 0;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- /*
- * Begin a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Write the record
- */
- ret = ltdb->kv_ops->store(ltdb, key, data, flags);
- assert_int_equal(ret, 0);
-
- /*
- * Commit the transaction
- */
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * And now read it back
- * Note there is no read transaction active
- */
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR);
-
- talloc_free(tmp_ctx);
-}
-
-/*
- * Test that data can be deleted from the kv store
- */
-static void test_delete(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- uint8_t key_val[] = "TheKey";
- struct ldb_val key = {
- .data = key_val,
- .length = sizeof(key_val)
- };
-
- uint8_t value[] = "The record contents";
- struct ldb_val data = {
- .data = value,
- .length = sizeof(value)
- };
-
- struct ldb_val read;
-
- int flags = 0;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- /*
- * Begin a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Write the record
- */
- ret = ltdb->kv_ops->store(ltdb, key, data, flags);
- assert_int_equal(ret, 0);
-
- /*
- * Commit the transaction
- */
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * And now read it back
- */
- ret = ltdb->kv_ops->lock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, 0);
- assert_int_equal(sizeof(value), read.length);
- assert_memory_equal(value, read.data, sizeof(value));
- ret = ltdb->kv_ops->unlock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
-
- /*
- * Begin a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Now delete it.
- */
- ret = ltdb->kv_ops->delete(ltdb, key);
- assert_int_equal(ret, 0);
-
- /*
- * Commit the transaction
- */
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * And now try to read it back
- */
- ret = ltdb->kv_ops->lock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
- ret = ltdb->kv_ops->unlock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
-
- talloc_free(tmp_ctx);
-}
-
-/*
- * Check that writes are correctly rolled back when a transaction
- * is rolled back.
- */
-static void test_transaction_abort_write(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- uint8_t key_val[] = "TheKey";
- struct ldb_val key = {
- .data = key_val,
- .length = sizeof(key_val)
- };
-
- uint8_t value[] = "The record contents";
- struct ldb_val data = {
- .data = value,
- .length = sizeof(value)
- };
-
- struct ldb_val read;
-
- int flags = 0;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- /*
- * Begin a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Write the record
- */
- ret = ltdb->kv_ops->store(ltdb, key, data, flags);
- assert_int_equal(ret, 0);
-
- /*
- * And now read it back
- */
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, 0);
- assert_int_equal(sizeof(value), read.length);
- assert_memory_equal(value, read.data, sizeof(value));
-
-
- /*
- * Now abort the transaction
- */
- ret = ltdb->kv_ops->abort_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * And now read it back, should not be there
- */
- ret = ltdb->kv_ops->lock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
- ret = ltdb->kv_ops->unlock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
-
- talloc_free(tmp_ctx);
-}
-
-/*
- * Check that deletes are correctly rolled back when a transaction is
- * aborted.
- */
-static void test_transaction_abort_delete(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- uint8_t key_val[] = "TheKey";
- struct ldb_val key = {
- .data = key_val,
- .length = sizeof(key_val)
- };
-
- uint8_t value[] = "The record contents";
- struct ldb_val data = {
- .data = value,
- .length = sizeof(value)
- };
-
- struct ldb_val read;
-
- int flags = 0;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- /*
- * Begin a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Write the record
- */
- ret = ltdb->kv_ops->store(ltdb, key, data, flags);
- assert_int_equal(ret, 0);
-
- /*
- * Commit the transaction
- */
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * And now read it back
- */
- ret = ltdb->kv_ops->lock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, 0);
- assert_int_equal(sizeof(value), read.length);
- assert_memory_equal(value, read.data, sizeof(value));
- ret = ltdb->kv_ops->unlock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
-
- /*
- * Begin a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Now delete it.
- */
- ret = ltdb->kv_ops->delete(ltdb, key);
- assert_int_equal(ret, 0);
-
- /*
- * And now read it back
- */
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
-
- /*
- * Abort the transaction
- */
- ret = ltdb->kv_ops->abort_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * And now try to read it back
- */
- ret = ltdb->kv_ops->lock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, 0);
- assert_int_equal(sizeof(value), read.length);
- assert_memory_equal(value, read.data, sizeof(value));
- ret = ltdb->kv_ops->unlock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
-
- talloc_free(tmp_ctx);
-}
-
-/*
- * Test that writes outside a transaction fail
- */
-static void test_write_outside_transaction(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- uint8_t key_val[] = "TheKey";
- struct ldb_val key = {
- .data = key_val,
- .length = sizeof(key_val)
- };
-
- uint8_t value[] = "The record contents";
- struct ldb_val data = {
- .data = value,
- .length = sizeof(value)
- };
-
-
- int flags = 0;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- /*
- * Attempt to write the record
- */
- ret = ltdb->kv_ops->store(ltdb, key, data, flags);
- assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR);
-
- talloc_free(tmp_ctx);
-}
-
-/*
- * Test data can not be deleted outside a transaction
- */
-static void test_delete_outside_transaction(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- uint8_t key_val[] = "TheKey";
- struct ldb_val key = {
- .data = key_val,
- .length = sizeof(key_val)
- };
-
- uint8_t value[] = "The record contents";
- struct ldb_val data = {
- .data = value,
- .length = sizeof(value)
- };
-
- struct ldb_val read;
-
- int flags = 0;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- /*
- * Begin a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Write the record
- */
- ret = ltdb->kv_ops->store(ltdb, key, data, flags);
- assert_int_equal(ret, 0);
-
- /*
- * Commit the transaction
- */
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * And now read it back
- */
- ret = ltdb->kv_ops->lock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, 0);
- assert_int_equal(sizeof(value), read.length);
- assert_memory_equal(value, read.data, sizeof(value));
- ret = ltdb->kv_ops->unlock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
-
- /*
- * Now attempt to delete a record
- */
- ret = ltdb->kv_ops->delete(ltdb, key);
- assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR);
-
- /*
- * And now read it back
- */
- ret = ltdb->kv_ops->lock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &read);
- assert_int_equal(ret, 0);
- assert_int_equal(sizeof(value), read.length);
- assert_memory_equal(value, read.data, sizeof(value));
- ret = ltdb->kv_ops->unlock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
-
- talloc_free(tmp_ctx);
-}
-
-static int traverse_fn(struct ltdb_private *ltdb,
- struct ldb_val key,
- struct ldb_val data,
- void *ctx) {
-
- int *visits = ctx;
- int i;
-
- if (strncmp("key ", (char *) key.data, 4) == 0) {
- i = strtol((char *) &key.data[4], NULL, 10);
- visits[i]++;
- }
- return LDB_SUCCESS;
-}
-
-
-/*
- * Test that iterate visits all the records.
- */
-static void test_iterate(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- int i;
- int num_recs = 1024;
- int visits[num_recs];
-
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- /*
- * Begin a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Write the records
- */
- for (i = 0; i < num_recs; i++) {
- struct ldb_val key;
- struct ldb_val rec;
- int flags = 0;
-
- visits[i] = 0;
- key.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", i);
- key.length = strlen((char *)key.data) + 1;
-
- rec.data = (uint8_t *) talloc_asprintf(tmp_ctx,
- "data for record (%04d)",
- i);
- rec.length = strlen((char *)rec.data) + 1;
-
- ret = ltdb->kv_ops->store(ltdb, key, rec, flags);
- assert_int_equal(ret, 0);
-
- TALLOC_FREE(key.data);
- TALLOC_FREE(rec.data);
- }
-
- /*
- * Commit the transaction
- */
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Now iterate over the kv store and ensure that all the
- * records are visited.
- */
- ret = ltdb->kv_ops->lock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
- ret = ltdb->kv_ops->iterate(ltdb, traverse_fn, visits);
- for (i = 0; i <num_recs; i++) {
- assert_int_equal(1, visits[i]);
- }
- ret = ltdb->kv_ops->unlock_read(test_ctx->ldb->modules);
- assert_int_equal(ret, 0);
-
- TALLOC_FREE(tmp_ctx);
-}
-
-struct update_context {
- struct ldb_context* ldb;
- int visits[NUM_RECS];
-};
-
-static int update_fn(struct ltdb_private *ltdb,
- struct ldb_val key,
- struct ldb_val data,
- void *ctx) {
-
- struct ldb_val new_key;
- struct ldb_module *module = NULL;
- struct update_context *context =NULL;
- int ret = LDB_SUCCESS;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(ltdb);
- assert_non_null(tmp_ctx);
-
- context = talloc_get_type_abort(ctx, struct update_context);
-
- module = talloc_zero(tmp_ctx, struct ldb_module);
- module->ldb = context->ldb;
-
- if (strncmp("key ", (char *) key.data, 4) == 0) {
- int i = strtol((char *) &key.data[4], NULL, 10);
- context->visits[i]++;
- new_key.data = talloc_memdup(tmp_ctx, key.data, key.length);
- new_key.length = key.length;
- new_key.data[0] = 'K';
-
- ret = ltdb->kv_ops->update_in_iterate(ltdb,
- key,
- new_key,
- data,
- &module);
- }
- TALLOC_FREE(tmp_ctx);
- return ret;
-}
-
-/*
- * Test that update_in_iterate behaves as expected.
- */
-static void test_update_in_iterate(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- int i;
- struct update_context *context = NULL;
-
-
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- context = talloc_zero(tmp_ctx, struct update_context);
- assert_non_null(context);
- context->ldb = test_ctx->ldb;
- /*
- * Begin a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Write the records
- */
- for (i = 0; i < NUM_RECS; i++) {
- struct ldb_val key;
- struct ldb_val rec;
- int flags = 0;
-
- key.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", i);
- key.length = strlen((char *)key.data) + 1;
-
- rec.data = (uint8_t *) talloc_asprintf(tmp_ctx,
- "data for record (%04d)",
- i);
- rec.length = strlen((char *)rec.data) + 1;
-
- ret = ltdb->kv_ops->store(ltdb, key, rec, flags);
- assert_int_equal(ret, 0);
-
- TALLOC_FREE(key.data);
- TALLOC_FREE(rec.data);
- }
-
- /*
- * Commit the transaction
- */
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
- /*
- * Now iterate over the kv store and ensure that all the
- * records are visited.
- */
-
- /*
- * Needs to be done inside a transaction
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- ret = ltdb->kv_ops->iterate(ltdb, update_fn, context);
- for (i = 0; i < NUM_RECS; i++) {
- assert_int_equal(1, context->visits[i]);
- }
-
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
- TALLOC_FREE(tmp_ctx);
-}
-
-/*
- * Ensure that writes are not visible until the transaction has been
- * committed.
- */
-static void test_write_transaction_isolation(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- struct ldb_val key;
- struct ldb_val val;
-
- const char *KEY1 = "KEY01";
- const char *VAL1 = "VALUE01";
-
- const char *KEY2 = "KEY02";
- const char *VAL2 = "VALUE02";
-
- /*
- * Pipes etc to co-ordinate the processes
- */
- int to_child[2];
- int to_parent[2];
- char buf[2];
- pid_t pid, w_pid;
- int wstatus;
-
- TALLOC_CTX *tmp_ctx;
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
-
- /*
- * Add a record to the database
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
- key.length = strlen(KEY1) + 1;
-
- val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL1);
- val.length = strlen(VAL1) + 1;
-
- ret = ltdb->kv_ops->store(ltdb, key, val, 0);
- assert_int_equal(ret, 0);
-
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
-
- ret = pipe(to_child);
- assert_int_equal(ret, 0);
- ret = pipe(to_parent);
- assert_int_equal(ret, 0);
- /*
- * Now fork a new process
- */
-
- pid = fork();
- if (pid == 0) {
-
- struct ldb_context *ldb = NULL;
- close(to_child[1]);
- close(to_parent[0]);
-
- /*
- * Wait for the transaction to start
- */
- ret = read(to_child[0], buf, 2);
- if (ret != 2) {
- print_error(__location__": read returned (%d)\n",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- ldb = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb, test_ctx->dbpath, 0, NULL);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": ldb_connect returned (%d)\n",
- ret);
- exit(ret);
- }
-
- ltdb = get_ltdb(ldb);
-
- ret = ltdb->kv_ops->lock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": lock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
- /*
- * Check that KEY1 is there
- */
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
- key.length = strlen(KEY1) + 1;
-
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &val);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": fetch_and_parse returned "
- "(%d)\n",
- ret);
- exit(ret);
- }
-
- if ((strlen(VAL1) + 1) != val.length) {
- print_error(__location__": KEY1 value lengths different"
- ", expected (%d) actual(%d)\n",
- (int)(strlen(VAL1) + 1), (int)val.length);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) {
- print_error(__location__": KEY1 values different, "
- "expected (%s) actual(%s)\n",
- VAL1,
- val.data);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- ret = ltdb->kv_ops->unlock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": unlock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
- /*
- * Check that KEY2 is not there
- */
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
- key.length = strlen(KEY2 + 1);
-
- ret = ltdb->kv_ops->lock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": lock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &val);
- if (ret != LDB_ERR_NO_SUCH_OBJECT) {
- print_error(__location__": fetch_and_parse returned "
- "(%d)\n",
- ret);
- exit(ret);
- }
-
- ret = ltdb->kv_ops->unlock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": unlock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
- /*
- * Signal the other process to commit the transaction
- */
- ret = write(to_parent[1], "GO", 2);
- if (ret != 2) {
- print_error(__location__": write returned (%d)\n",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- /*
- * Wait for the transaction to be commited
- */
- ret = read(to_child[0], buf, 2);
- if (ret != 2) {
- print_error(__location__": read returned (%d)\n",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- /*
- * Check that KEY1 is there
- */
- ret = ltdb->kv_ops->lock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": unlock_read returned (%d)\n",
- ret);
- exit(ret);
- }
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
- key.length = strlen(KEY1) + 1;
-
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &val);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": fetch_and_parse returned "
- "(%d)\n",
- ret);
- exit(ret);
- }
-
- if ((strlen(VAL1) + 1) != val.length) {
- print_error(__location__": KEY1 value lengths different"
- ", expected (%d) actual(%d)\n",
- (int)(strlen(VAL1) + 1), (int)val.length);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) {
- print_error(__location__": KEY1 values different, "
- "expected (%s) actual(%s)\n",
- VAL1,
- val.data);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- ret = ltdb->kv_ops->unlock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": unlock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
-
- /*
- * Check that KEY2 is there
- */
- ret = ltdb->kv_ops->lock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": unlock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
- key.length = strlen(KEY2) + 1;
-
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &val);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": fetch_and_parse returned "
- "(%d)\n",
- ret);
- exit(ret);
- }
-
- if ((strlen(VAL2) + 1) != val.length) {
- print_error(__location__": KEY2 value lengths different"
- ", expected (%d) actual(%d)\n",
- (int)(strlen(VAL2) + 1), (int)val.length);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- if (memcmp(VAL2, val.data, strlen(VAL2)) != 0) {
- print_error(__location__": KEY2 values different, "
- "expected (%s) actual(%s)\n",
- VAL2,
- val.data);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- ret = ltdb->kv_ops->unlock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": unlock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
- exit(0);
- }
- close(to_child[0]);
- close(to_parent[1]);
-
- /*
- * Begin a transaction and add a record to the database
- * but leave the transaction open
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
- key.length = strlen(KEY2) + 1;
-
- val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL2);
- val.length = strlen(VAL2) + 1;
-
- ret = ltdb->kv_ops->store(ltdb, key, val, 0);
- assert_int_equal(ret, 0);
-
- /*
- * Signal the child process
- */
- ret = write(to_child[1], "GO", 2);
- assert_int_equal(2, ret);
-
- /*
- * Wait for the child process to check the DB state while the
- * transaction is active
- */
- ret = read(to_parent[0], buf, 2);
- assert_int_equal(2, ret);
-
- /*
- * commit the transaction
- */
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(0, ret);
-
- /*
- * Signal the child process
- */
- ret = write(to_child[1], "GO", 2);
- assert_int_equal(2, ret);
-
- w_pid = waitpid(pid, &wstatus, 0);
- assert_int_equal(pid, w_pid);
-
- assert_true(WIFEXITED(wstatus));
-
- assert_int_equal(WEXITSTATUS(wstatus), 0);
-
-
- TALLOC_FREE(tmp_ctx);
-}
-
-/*
- * Ensure that deletes are not visible until the transaction has been
- * committed.
- */
-static void test_delete_transaction_isolation(void **state)
-{
- int ret;
- struct test_ctx *test_ctx = talloc_get_type_abort(*state,
- struct test_ctx);
- struct ltdb_private *ltdb = get_ltdb(test_ctx->ldb);
- struct ldb_val key;
- struct ldb_val val;
-
- const char *KEY1 = "KEY01";
- const char *VAL1 = "VALUE01";
-
- const char *KEY2 = "KEY02";
- const char *VAL2 = "VALUE02";
-
- /*
- * Pipes etc to co-ordinate the processes
- */
- int to_child[2];
- int to_parent[2];
- char buf[2];
- pid_t pid, w_pid;
- int wstatus;
-
- TALLOC_CTX *tmp_ctx;
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
-
- /*
- * Add records to the database
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
- key.length = strlen(KEY1) + 1;
-
- val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL1);
- val.length = strlen(VAL1) + 1;
-
- ret = ltdb->kv_ops->store(ltdb, key, val, 0);
- assert_int_equal(ret, 0);
-
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
- key.length = strlen(KEY2) + 1;
-
- val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL2);
- val.length = strlen(VAL2) + 1;
-
- ret = ltdb->kv_ops->store(ltdb, key, val, 0);
- assert_int_equal(ret, 0);
-
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(ret, 0);
-
-
- ret = pipe(to_child);
- assert_int_equal(ret, 0);
- ret = pipe(to_parent);
- assert_int_equal(ret, 0);
- /*
- * Now fork a new process
- */
-
- pid = fork();
- if (pid == 0) {
-
- struct ldb_context *ldb = NULL;
- close(to_child[1]);
- close(to_parent[0]);
-
- /*
- * Wait for the transaction to be started
- */
- ret = read(to_child[0], buf, 2);
- if (ret != 2) {
- print_error(__location__": read returned (%d)\n",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- ldb = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb, test_ctx->dbpath, 0, NULL);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": ldb_connect returned (%d)\n",
- ret);
- exit(ret);
- }
-
- ltdb = get_ltdb(ldb);
-
- ret = ltdb->kv_ops->lock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": lock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
- /*
- * Check that KEY1 is there
- */
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
- key.length = strlen(KEY1) + 1;
-
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &val);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": fetch_and_parse returned "
- "(%d)\n",
- ret);
- exit(ret);
- }
-
- if ((strlen(VAL1) + 1) != val.length) {
- print_error(__location__": KEY1 value lengths different"
- ", expected (%d) actual(%d)\n",
- (int)(strlen(VAL1) + 1), (int)val.length);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) {
- print_error(__location__": KEY1 values different, "
- "expected (%s) actual(%s)\n",
- VAL1,
- val.data);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- /*
- * Check that KEY2 is there
- */
-
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
- key.length = strlen(KEY2) + 1;
-
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &val);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": fetch_and_parse returned "
- "(%d)\n",
- ret);
- exit(ret);
- }
-
- if ((strlen(VAL2) + 1) != val.length) {
- print_error(__location__": KEY2 value lengths different"
- ", expected (%d) actual(%d)\n",
- (int)(strlen(VAL2) + 1), (int)val.length);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- if (memcmp(VAL2, val.data, strlen(VAL2)) != 0) {
- print_error(__location__": KEY2 values different, "
- "expected (%s) actual(%s)\n",
- VAL2,
- val.data);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- ret = ltdb->kv_ops->unlock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": unlock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
- /*
- * Signal the other process to commit the transaction
- */
- ret = write(to_parent[1], "GO", 2);
- if (ret != 2) {
- print_error(__location__": write returned (%d)\n",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- /*
- * Wait for the transaction to be commited
- */
- ret = read(to_child[0], buf, 2);
- if (ret != 2) {
- print_error(__location__": read returned (%d)\n",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- /*
- * Check that KEY1 is there
- */
- ret = ltdb->kv_ops->lock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": unlock_read returned (%d)\n",
- ret);
- exit(ret);
- }
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
- key.length = strlen(KEY1) + 1;
-
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &val);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": fetch_and_parse returned "
- "(%d)\n",
- ret);
- exit(ret);
- }
-
- if ((strlen(VAL1) + 1) != val.length) {
- print_error(__location__": KEY1 value lengths different"
- ", expected (%d) actual(%d)\n",
- (int)(strlen(VAL1) + 1), (int)val.length);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) {
- print_error(__location__": KEY1 values different, "
- "expected (%s) actual(%s)\n",
- VAL1,
- val.data);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
-
- /*
- * Check that KEY2 is not there
- */
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
- key.length = strlen(KEY2 + 1);
-
- ret = ltdb->kv_ops->lock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": lock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
- ret = ltdb->kv_ops->fetch_and_parse(ltdb, key, parse, &val);
- if (ret != LDB_ERR_NO_SUCH_OBJECT) {
- print_error(__location__": fetch_and_parse returned "
- "(%d)\n",
- ret);
- exit(ret);
- }
-
- ret = ltdb->kv_ops->unlock_read(ldb->modules);
- if (ret != LDB_SUCCESS) {
- print_error(__location__": unlock_read returned (%d)\n",
- ret);
- exit(ret);
- }
-
- exit(0);
- }
- close(to_child[0]);
- close(to_parent[1]);
-
- /*
- * Begin a transaction and delete a record from the database
- * but leave the transaction open
- */
- ret = ltdb->kv_ops->begin_write(ltdb);
- assert_int_equal(ret, 0);
-
- key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
- key.length = strlen(KEY2) + 1;
-
- ret = ltdb->kv_ops->delete(ltdb, key);
- assert_int_equal(ret, 0);
- /*
- * Signal the child process
- */
- ret = write(to_child[1], "GO", 2);
- assert_int_equal(2, ret);
-
- /*
- * Wait for the child process to check the DB state while the
- * transaction is active
- */
- ret = read(to_parent[0], buf, 2);
- assert_int_equal(2, ret);
-
- /*
- * commit the transaction
- */
- ret = ltdb->kv_ops->finish_write(ltdb);
- assert_int_equal(0, ret);
-
- /*
- * Signal the child process
- */
- ret = write(to_child[1], "GO", 2);
- assert_int_equal(2, ret);
-
- w_pid = waitpid(pid, &wstatus, 0);
- assert_int_equal(pid, w_pid);
-
- assert_true(WIFEXITED(wstatus));
-
- assert_int_equal(WEXITSTATUS(wstatus), 0);
-
-
- TALLOC_FREE(tmp_ctx);
-}
-
-
-int main(int argc, const char **argv)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test_setup_teardown(
- test_add_get,
- setup,
- teardown),
- cmocka_unit_test_setup_teardown(
- test_delete,
- setup,
- teardown),
- cmocka_unit_test_setup_teardown(
- test_transaction_abort_write,
- setup,
- teardown),
- cmocka_unit_test_setup_teardown(
- test_transaction_abort_delete,
- setup,
- teardown),
- cmocka_unit_test_setup_teardown(
- test_read_outside_transaction,
- setup,
- teardown),
- cmocka_unit_test_setup_teardown(
- test_write_outside_transaction,
- setup,
- teardown),
- cmocka_unit_test_setup_teardown(
- test_delete_outside_transaction,
- setup,
- teardown),
- cmocka_unit_test_setup_teardown(
- test_iterate,
- setup,
- teardown),
- cmocka_unit_test_setup_teardown(
- test_update_in_iterate,
- setup,
- teardown),
- cmocka_unit_test_setup_teardown(
- test_write_transaction_isolation,
- setup,
- teardown),
- cmocka_unit_test_setup_teardown(
- test_delete_transaction_isolation,
- setup,
- teardown),
- };
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/ldb_lmdb_size_test.c b/tests/ldb_lmdb_size_test.c
deleted file mode 100644
index af015fa..0000000
--- a/tests/ldb_lmdb_size_test.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * lmdb backend specific tests for ldb
- * Tests for truncated index keys
- *
- * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/*
- * These tests confirm that database sizes of > 4GB are supported
- * Due to the disk space requirement they are not run as part of the normal
- * self test runs.
- *
- * Setup and tear down code copied from ldb_mod_op_test.c
- */
-
-/*
- * from cmocka.c:
- * These headers or their equivalents should be included prior to
- * including
- * this header file.
- *
- * #include <stdarg.h>
- * #include <stddef.h>
- * #include <setjmp.h>
- *
- * This allows test applications to use custom definitions of C standard
- * library functions and types.
- *
- */
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <errno.h>
-#include <unistd.h>
-#include <talloc.h>
-#include <tevent.h>
-#include <ldb.h>
-#include <ldb_module.h>
-#include <ldb_private.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <sys/wait.h>
-
-#include <lmdb.h>
-
-
-#define TEST_BE "mdb"
-
-struct ldbtest_ctx {
- struct tevent_context *ev;
- struct ldb_context *ldb;
-
- const char *dbfile;
- const char *lockfile; /* lockfile is separate */
-
- const char *dbpath;
-};
-
-static void unlink_old_db(struct ldbtest_ctx *test_ctx)
-{
- int ret;
-
- errno = 0;
- ret = unlink(test_ctx->lockfile);
- if (ret == -1 && errno != ENOENT) {
- fail();
- }
-
- errno = 0;
- ret = unlink(test_ctx->dbfile);
- if (ret == -1 && errno != ENOENT) {
- fail();
- }
-}
-
-static int ldbtest_noconn_setup(void **state)
-{
- struct ldbtest_ctx *test_ctx;
-
- test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
- assert_non_null(test_ctx);
-
- test_ctx->ev = tevent_context_init(test_ctx);
- assert_non_null(test_ctx->ev);
-
- test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
- assert_non_null(test_ctx->ldb);
-
- test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
- assert_non_null(test_ctx->dbfile);
-
- test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
- test_ctx->dbfile);
- assert_non_null(test_ctx->lockfile);
-
- test_ctx->dbpath = talloc_asprintf(test_ctx,
- TEST_BE"://%s", test_ctx->dbfile);
- assert_non_null(test_ctx->dbpath);
-
- unlink_old_db(test_ctx);
- *state = test_ctx;
- return 0;
-}
-
-static int ldbtest_noconn_teardown(void **state)
-{
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
-
- unlink_old_db(test_ctx);
- talloc_free(test_ctx);
- return 0;
-}
-
-static int ldbtest_setup(void **state)
-{
- struct ldbtest_ctx *test_ctx;
- int ret;
-
- ldbtest_noconn_setup((void **) &test_ctx);
-
- ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
-
- *state = test_ctx;
- return 0;
-}
-
-static int ldbtest_teardown(void **state)
-{
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- ldbtest_noconn_teardown((void **) &test_ctx);
- return 0;
-}
-
-static void test_db_size_gt_4GB(void **state)
-{
- int ret, x;
- struct ldb_message *msg;
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- const int MB = 1024 * 1024;
- char *blob = NULL;
-
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
-
- blob = talloc_zero_size(tmp_ctx, (MB + 1));
- assert_non_null(blob);
- memset(blob, 'x', MB);
-
-
- for (x = 0; x < 6144; x++) {
- msg = ldb_msg_new(tmp_ctx);
- assert_non_null(msg);
-
- msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test%d", x);
- assert_non_null(msg->dn);
-
- ldb_transaction_start(test_ctx->ldb);
- ret = ldb_msg_add_string(msg, "blob", blob);
- assert_int_equal(ret, 0);
-
- ret = ldb_add(test_ctx->ldb, msg);
- assert_int_equal(ret, 0);
- ldb_transaction_commit(test_ctx->ldb);
-
- TALLOC_FREE(msg);
- }
- talloc_free(tmp_ctx);
- {
- struct stat s;
- ret = stat(test_ctx->dbfile, &s);
- assert_int_equal(ret, 0);
- assert_true(s.st_size > (6144LL * MB));
- }
-}
-
-int main(int argc, const char **argv)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test_setup_teardown(
- test_db_size_gt_4GB,
- ldbtest_setup,
- ldbtest_teardown),
- };
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/ldb_lmdb_test.c b/tests/ldb_lmdb_test.c
deleted file mode 100644
index a254a84..0000000
--- a/tests/ldb_lmdb_test.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * lmdb backend specific tests for ldb
- *
- * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/*
- * lmdb backend specific tests for ldb
- *
- * Setup and tear down code copied from ldb_mod_op_test.c
- */
-
-/*
- * from cmocka.c:
- * These headers or their equivalents should be included prior to
- * including
- * this header file.
- *
- * #include <stdarg.h>
- * #include <stddef.h>
- * #include <setjmp.h>
- *
- * This allows test applications to use custom definitions of C standard
- * library functions and types.
- *
- */
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <errno.h>
-#include <unistd.h>
-#include <talloc.h>
-#include <tevent.h>
-#include <ldb.h>
-#include <ldb_module.h>
-#include <ldb_private.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <sys/wait.h>
-
-#include "../ldb_tdb/ldb_tdb.h"
-#include "../ldb_mdb/ldb_mdb.h"
-
-#define TEST_BE "mdb"
-
-#define LMDB_MAX_KEY_SIZE 511
-
-struct ldbtest_ctx {
- struct tevent_context *ev;
- struct ldb_context *ldb;
-
- const char *dbfile;
- const char *lockfile; /* lockfile is separate */
-
- const char *dbpath;
-};
-
-static void unlink_old_db(struct ldbtest_ctx *test_ctx)
-{
- int ret;
-
- errno = 0;
- ret = unlink(test_ctx->lockfile);
- if (ret == -1 && errno != ENOENT) {
- fail();
- }
-
- errno = 0;
- ret = unlink(test_ctx->dbfile);
- if (ret == -1 && errno != ENOENT) {
- fail();
- }
-}
-
-static int ldbtest_noconn_setup(void **state)
-{
- struct ldbtest_ctx *test_ctx;
-
- test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
- assert_non_null(test_ctx);
-
- test_ctx->ev = tevent_context_init(test_ctx);
- assert_non_null(test_ctx->ev);
-
- test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
- assert_non_null(test_ctx->ldb);
-
- test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
- assert_non_null(test_ctx->dbfile);
-
- test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
- test_ctx->dbfile);
- assert_non_null(test_ctx->lockfile);
-
- test_ctx->dbpath = talloc_asprintf(test_ctx,
- TEST_BE"://%s", test_ctx->dbfile);
- assert_non_null(test_ctx->dbpath);
-
- unlink_old_db(test_ctx);
- *state = test_ctx;
- return 0;
-}
-
-static int ldbtest_noconn_teardown(void **state)
-{
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
-
- unlink_old_db(test_ctx);
- talloc_free(test_ctx);
- return 0;
-}
-
-static int ldbtest_setup(void **state)
-{
- struct ldbtest_ctx *test_ctx;
- int ret;
- struct ldb_ldif *ldif;
- const char *index_ldif = \
- "dn: @INDEXLIST\n"
- "@IDXGUID: objectUUID\n"
- "@IDX_DN_GUID: GUID\n"
- "\n";
-
- ldbtest_noconn_setup((void **) &test_ctx);
-
- ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
-
- while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) {
- ret = ldb_add(test_ctx->ldb, ldif->msg);
- assert_int_equal(ret, LDB_SUCCESS);
- }
- *state = test_ctx;
- return 0;
-}
-
-static int ldbtest_teardown(void **state)
-{
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- ldbtest_noconn_teardown((void **) &test_ctx);
- return 0;
-}
-
-static void test_ldb_add_key_len_gt_max(void **state)
-{
- int ret;
- int xs_size = 0;
- struct ldb_message *msg;
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- char *xs = NULL;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- msg = ldb_msg_new(tmp_ctx);
- assert_non_null(msg);
-
- /*
- * The zero terminator is part of the key if we were not in
- * GUID mode
- */
-
- xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */
- xs_size += 1; /* want key on char too long */
- xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
- memset(xs, 'x', xs_size);
-
- msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs);
- assert_non_null(msg->dn);
-
- ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
- assert_int_equal(ret, 0);
-
- ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
- assert_int_equal(ret, 0);
-
- ret = ldb_add(test_ctx->ldb, msg);
- assert_int_equal(ret, LDB_SUCCESS);
-
- talloc_free(tmp_ctx);
-}
-
-static void test_ldb_add_key_len_2x_gt_max(void **state)
-{
- int ret;
- int xs_size = 0;
- struct ldb_message *msg;
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- char *xs = NULL;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- msg = ldb_msg_new(tmp_ctx);
- assert_non_null(msg);
-
- /*
- * The zero terminator is part of the key if we were not in
- * GUID mode
- */
-
- xs_size = 2 * LMDB_MAX_KEY_SIZE;
- xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
- memset(xs, 'x', xs_size);
-
- msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs);
- assert_non_null(msg->dn);
-
- ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
- assert_int_equal(ret, 0);
-
- ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
- assert_int_equal(ret, 0);
-
- ret = ldb_add(test_ctx->ldb, msg);
- assert_int_equal(ret, LDB_SUCCESS);
-
- talloc_free(tmp_ctx);
-}
-
-static void test_ldb_add_key_len_eq_max(void **state)
-{
- int ret;
- int xs_size = 0;
- struct ldb_message *msg;
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- char *xs = NULL;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- msg = ldb_msg_new(tmp_ctx);
- assert_non_null(msg);
-
- /*
- * The zero terminator is part of the key if we were not in
- * GUID mode
- */
-
- xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */
- xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
- memset(xs, 'x', xs_size);
-
- msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs);
- assert_non_null(msg->dn);
-
- ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
- assert_int_equal(ret, 0);
-
- ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
- assert_int_equal(ret, 0);
-
- ret = ldb_add(test_ctx->ldb, msg);
- assert_int_equal(ret, 0);
-
- talloc_free(tmp_ctx);
-}
-
-static int ldbtest_setup_noguid(void **state)
-{
- struct ldbtest_ctx *test_ctx;
- int ret;
-
- ldbtest_noconn_setup((void **) &test_ctx);
-
- ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
-
- *state = test_ctx;
- return 0;
-}
-
-static void test_ldb_add_special_key_len_gt_max(void **state)
-{
- int ret;
- int xs_size = 0;
- struct ldb_message *msg;
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- char *xs = NULL;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- msg = ldb_msg_new(tmp_ctx);
- assert_non_null(msg);
-
- /*
- * The zero terminator is part of the key if we were not in
- * GUID mode
- */
-
- xs_size = LMDB_MAX_KEY_SIZE - 5; /* "dn=@" and the zero terminator */
- xs_size += 1; /* want key on char too long */
- xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
- memset(xs, 'x', xs_size);
-
- msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "@%s", xs);
- assert_non_null(msg->dn);
-
- ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
- assert_int_equal(ret, 0);
-
- ret = ldb_add(test_ctx->ldb, msg);
- assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR);
-
- talloc_free(tmp_ctx);
-}
-
-static void test_ldb_add_special_key_len_eq_max(void **state)
-{
- int ret;
- int xs_size = 0;
- struct ldb_message *msg;
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- char *xs = NULL;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- msg = ldb_msg_new(tmp_ctx);
- assert_non_null(msg);
-
- /*
- * The zero terminator is part of the key if we were not in
- * GUID mode
- */
-
- xs_size = LMDB_MAX_KEY_SIZE - 5; /* "dn=@" and the zero terminator */
- xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
- memset(xs, 'x', xs_size);
-
- msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "@%s", xs);
- assert_non_null(msg->dn);
-
- ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
- assert_int_equal(ret, 0);
-
- ret = ldb_add(test_ctx->ldb, msg);
- assert_int_equal(ret, LDB_SUCCESS);
-
- talloc_free(tmp_ctx);
-}
-
-static void test_ldb_add_dn_no_guid_mode(void **state)
-{
- int ret;
- int xs_size = 0;
- struct ldb_message *msg;
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- char *xs = NULL;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(test_ctx);
- assert_non_null(tmp_ctx);
-
- msg = ldb_msg_new(tmp_ctx);
- assert_non_null(msg);
-
- /*
- * The zero terminator is part of the key if we were not in
- * GUID mode
- */
-
- xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */
- xs_size += 1; /* want key on char too long */
- xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
- memset(xs, 'x', xs_size);
-
- msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs);
- assert_non_null(msg->dn);
-
- ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
- assert_int_equal(ret, 0);
-
- ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
- assert_int_equal(ret, 0);
-
- ret = ldb_add(test_ctx->ldb, msg);
- assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
-
- talloc_free(tmp_ctx);
-}
-
-static struct MDB_env *get_mdb_env(struct ldb_context *ldb)
-{
- void *data = NULL;
- struct ltdb_private *ltdb = NULL;
- struct lmdb_private *lmdb = NULL;
- struct MDB_env *env = NULL;
-
- data = ldb_module_get_private(ldb->modules);
- assert_non_null(data);
-
- ltdb = talloc_get_type(data, struct ltdb_private);
- assert_non_null(ltdb);
-
- lmdb = ltdb->lmdb_private;
- assert_non_null(lmdb);
-
- env = lmdb->env;
- assert_non_null(env);
-
- return env;
-}
-
-static void test_multiple_opens(void **state)
-{
- struct ldb_context *ldb1 = NULL;
- struct ldb_context *ldb2 = NULL;
- struct ldb_context *ldb3 = NULL;
- struct MDB_env *env1 = NULL;
- struct MDB_env *env2 = NULL;
- struct MDB_env *env3 = NULL;
- int ret;
- struct ldbtest_ctx *test_ctx = NULL;
-
- test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
-
- /*
- * Open the database again
- */
- ldb1 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- ldb2 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- ldb3 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
- /*
- * We now have 3 ldb's open pointing to the same on disk database
- * they should all share the same MDB_env
- */
- env1 = get_mdb_env(ldb1);
- env2 = get_mdb_env(ldb2);
- env3 = get_mdb_env(ldb3);
-
- assert_ptr_equal(env1, env2);
- assert_ptr_equal(env1, env3);
-}
-
-static void test_multiple_opens_across_fork(void **state)
-{
- struct ldb_context *ldb1 = NULL;
- struct ldb_context *ldb2 = NULL;
- struct MDB_env *env1 = NULL;
- struct MDB_env *env2 = NULL;
- int ret;
- struct ldbtest_ctx *test_ctx = NULL;
- int pipes[2];
- char buf[2];
- int wstatus;
- pid_t pid, child_pid;
-
- test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
-
- /*
- * Open the database again
- */
- ldb1 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- ldb2 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- env1 = get_mdb_env(ldb1);
- env2 = get_mdb_env(ldb2);
-
- ret = pipe(pipes);
- assert_int_equal(ret, 0);
-
- child_pid = fork();
- if (child_pid == 0) {
- struct ldb_context *ldb3 = NULL;
- struct MDB_env *env3 = NULL;
-
- close(pipes[0]);
- ldb3 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
- if (ret != 0) {
- print_error(__location__": ldb_connect returned (%d)\n",
- ret);
- exit(ret);
- }
- env3 = get_mdb_env(ldb3);
- if (env1 != env2) {
- print_error(__location__": env1 != env2\n");
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- if (env1 == env3) {
- print_error(__location__": env1 == env3\n");
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- ret = write(pipes[1], "GO", 2);
- if (ret != 2) {
- print_error(__location__
- " write returned (%d)",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- exit(LDB_SUCCESS);
- }
- close(pipes[1]);
- ret = read(pipes[0], buf, 2);
- assert_int_equal(ret, 2);
-
- pid = waitpid(child_pid, &wstatus, 0);
- assert_int_equal(pid, child_pid);
-
- assert_true(WIFEXITED(wstatus));
-
- assert_int_equal(WEXITSTATUS(wstatus), 0);
-}
-
-int main(int argc, const char **argv)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test_setup_teardown(
- test_ldb_add_key_len_eq_max,
- ldbtest_setup,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_ldb_add_key_len_gt_max,
- ldbtest_setup,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_ldb_add_key_len_2x_gt_max,
- ldbtest_setup,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_ldb_add_special_key_len_eq_max,
- ldbtest_setup_noguid,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_ldb_add_special_key_len_gt_max,
- ldbtest_setup_noguid,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_ldb_add_dn_no_guid_mode,
- ldbtest_setup_noguid,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_multiple_opens,
- ldbtest_setup,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_multiple_opens_across_fork,
- ldbtest_setup,
- ldbtest_teardown),
- };
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/ldb_mod_op_test.c b/tests/ldb_mod_op_test.c
index 01667af..c8b9c1a 100644
--- a/tests/ldb_mod_op_test.c
+++ b/tests/ldb_mod_op_test.c
@@ -38,12 +38,6 @@
#define TEST_BE DEFAULT_BE
#endif /* TEST_BE */
-#ifdef TEST_LMDB
-#include "lmdb.h"
-#include "../ldb_tdb/ldb_tdb.h"
-#include "../ldb_mdb/ldb_mdb.h"
-#endif
-
struct ldbtest_ctx {
struct tevent_context *ev;
struct ldb_context *ldb;
@@ -208,16 +202,6 @@ static void test_ldif_message_redacted(void **state)
static int ldbtest_setup(void **state)
{
struct ldbtest_ctx *test_ctx;
- struct ldb_ldif *ldif;
-#ifdef GUID_IDX
- const char *index_ldif = \
- "dn: @INDEXLIST\n"
- "@IDXGUID: objectUUID\n"
- "@IDX_DN_GUID: GUID\n"
- "\n";
-#else
- const char *index_ldif = "\n";
-#endif
int ret;
ldbtest_noconn_setup((void **) &test_ctx);
@@ -225,10 +209,6 @@ static int ldbtest_setup(void **state)
ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
assert_int_equal(ret, 0);
- while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) {
- ret = ldb_add(test_ctx->ldb, ldif->msg);
- assert_int_equal(ret, LDB_SUCCESS);
- }
*state = test_ctx;
return 0;
}
@@ -261,9 +241,6 @@ static void test_ldb_add(void **state)
ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
assert_int_equal(ret, 0);
- ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
- assert_int_equal(ret, 0);
-
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, 0);
@@ -302,9 +279,6 @@ static void test_ldb_search(void **state)
ret = ldb_msg_add_string(msg, "cn", "test_cn_val1");
assert_int_equal(ret, 0);
- ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde1");
- assert_int_equal(ret, 0);
-
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, 0);
@@ -320,9 +294,6 @@ static void test_ldb_search(void **state)
ret = ldb_msg_add_string(msg, "cn", "test_cn_val2");
assert_int_equal(ret, 0);
- ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde2");
- assert_int_equal(ret, 0);
-
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, 0);
@@ -419,8 +390,7 @@ static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx,
static void add_dn_with_cn(struct ldbtest_ctx *test_ctx,
struct ldb_dn *dn,
- const char *cn_value,
- const char *uuid_value)
+ const char *cn_value)
{
int ret;
TALLOC_CTX *tmp_ctx;
@@ -439,9 +409,6 @@ static void add_dn_with_cn(struct ldbtest_ctx *test_ctx,
ret = ldb_msg_add_string(msg, "cn", cn_value);
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg, "objectUUID", uuid_value);
- assert_int_equal(ret, 0);
-
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, LDB_SUCCESS);
@@ -461,9 +428,7 @@ static void test_ldb_del(void **state)
dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn);
assert_non_null(dn);
- add_dn_with_cn(test_ctx, dn,
- "test_del_cn_val",
- "0123456789abcdef");
+ add_dn_with_cn(test_ctx, dn, "test_del_cn_val");
ret = ldb_delete(test_ctx->ldb, dn);
assert_int_equal(ret, LDB_SUCCESS);
@@ -587,8 +552,7 @@ static void test_ldb_build_search_req(void **state)
static void add_keyval(struct ldbtest_ctx *test_ctx,
const char *key,
- const char *val,
- const char *uuid)
+ const char *val)
{
int ret;
struct ldb_message *msg;
@@ -602,9 +566,6 @@ static void add_keyval(struct ldbtest_ctx *test_ctx,
ret = ldb_msg_add_string(msg, key, val);
assert_int_equal(ret, 0);
- ret = ldb_msg_add_string(msg, "objectUUID", uuid);
- assert_int_equal(ret, 0);
-
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, 0);
@@ -640,8 +601,7 @@ static void test_transactions(void **state)
ret = ldb_transaction_start(test_ctx->ldb);
assert_int_equal(ret, 0);
- add_keyval(test_ctx, "vegetable", "carrot",
- "0123456789abcde0");
+ add_keyval(test_ctx, "vegetable", "carrot");
/* commit lev-0 transaction */
ret = ldb_transaction_commit(test_ctx->ldb);
@@ -651,8 +611,7 @@ static void test_transactions(void **state)
ret = ldb_transaction_start(test_ctx->ldb);
assert_int_equal(ret, 0);
- add_keyval(test_ctx, "fruit", "apple",
- "0123456789abcde1");
+ add_keyval(test_ctx, "fruit", "apple");
/* abort lev-1 nested transaction */
ret = ldb_transaction_cancel(test_ctx->ldb);
@@ -667,48 +626,6 @@ static void test_transactions(void **state)
assert_int_equal(res->count, 0);
}
-static void test_nested_transactions(void **state)
-{
- int ret;
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- struct ldb_result *res;
-
- /* start lev-0 transaction */
- ret = ldb_transaction_start(test_ctx->ldb);
- assert_int_equal(ret, 0);
-
- add_keyval(test_ctx, "vegetable", "carrot",
- "0123456789abcde0");
-
-
- /* start another lev-1 nested transaction */
- ret = ldb_transaction_start(test_ctx->ldb);
- assert_int_equal(ret, 0);
-
- add_keyval(test_ctx, "fruit", "apple",
- "0123456789abcde1");
-
- /* abort lev-1 nested transaction */
- ret = ldb_transaction_cancel(test_ctx->ldb);
- assert_int_equal(ret, 0);
-
- /* commit lev-0 transaction */
- ret = ldb_transaction_commit(test_ctx->ldb);
- assert_int_equal(ret, 0);
-
- res = get_keyval(test_ctx, "vegetable", "carrot");
- assert_non_null(res);
- assert_int_equal(res->count, 1);
-
- /* This documents the current ldb behaviour, i.e. nested
- * transactions are not supported. And the cancellation of the nested
- * transaction has no effect.
- */
- res = get_keyval(test_ctx, "fruit", "apple");
- assert_non_null(res);
- assert_int_equal(res->count, 1);
-}
struct ldb_mod_test_ctx {
struct ldbtest_ctx *ldb_test_ctx;
const char *entry_dn;
@@ -868,7 +785,6 @@ static int ldb_modify_test_setup(void **state)
struct ldb_mod_test_ctx *mod_test_ctx;
struct keyval kvs[] = {
{ "cn", "test_mod_cn" },
- { "objectUUID", "0123456789abcdef"},
{ NULL, NULL },
};
@@ -1173,7 +1089,6 @@ static int ldb_search_test_setup(void **state)
{ "cn", "test_search_cn2" },
{ "uid", "test_search_uid" },
{ "uid", "test_search_uid2" },
- { "objectUUID", "0123456789abcde0"},
{ NULL, NULL },
};
struct keyval kvs2[] = {
@@ -1181,7 +1096,6 @@ static int ldb_search_test_setup(void **state)
{ "cn", "test_search_2_cn2" },
{ "uid", "test_search_2_uid" },
{ "uid", "test_search_2_uid2" },
- { "objectUUID", "0123456789abcde1"},
{ NULL, NULL },
};
@@ -1530,7 +1444,6 @@ static int test_ldb_search_against_transaction_callback1(struct ldb_request *req
struct ldb_message *msg;
TALLOC_FREE(ctx->test_ctx->ldb);
TALLOC_FREE(ctx->test_ctx->ev);
- close(pipes[0]);
ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
if (ctx->test_ctx->ev == NULL) {
exit(LDB_ERR_OPERATIONS_ERROR);
@@ -1579,12 +1492,6 @@ static int test_ldb_search_against_transaction_callback1(struct ldb_request *req
exit(LDB_ERR_OPERATIONS_ERROR);
}
- ret = ldb_msg_add_string(msg, "objectUUID",
- "0123456789abcdef");
- if (ret != 0) {
- exit(ret);
- }
-
ret = ldb_add(ctx->test_ctx->ldb, msg);
if (ret != 0) {
exit(ret);
@@ -1593,7 +1500,7 @@ static int test_ldb_search_against_transaction_callback1(struct ldb_request *req
ret = ldb_transaction_commit(ctx->test_ctx->ldb);
exit(ret);
}
- close(pipes[1]);
+
ret = read(pipes[0], buf, 2);
assert_int_equal(ret, 2);
@@ -1767,7 +1674,6 @@ static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
struct ldb_dn *dn, *new_dn;
TALLOC_FREE(ctx->test_ctx->ldb);
TALLOC_FREE(ctx->test_ctx->ev);
- close(pipes[0]);
ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
if (ctx->test_ctx->ev == NULL) {
exit(LDB_ERR_OPERATIONS_ERROR);
@@ -1834,7 +1740,6 @@ static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
struct ldb_message_element *el;
TALLOC_FREE(ctx->test_ctx->ldb);
TALLOC_FREE(ctx->test_ctx->ev);
- close(pipes[0]);
ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
if (ctx->test_ctx->ev == NULL) {
exit(LDB_ERR_OPERATIONS_ERROR);
@@ -1910,7 +1815,6 @@ static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
* sending the "GO" as it is blocked at ldb_transaction_start().
*/
- close(pipes[1]);
ret = read(pipes[0], buf, 2);
assert_int_equal(ret, 2);
@@ -1950,13 +1854,10 @@ static void test_ldb_modify_during_search(void **state, bool add_index,
ret = ldb_msg_add_string(msg, "@IDXATTR", "cn");
assert_int_equal(ret, LDB_SUCCESS);
+
ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb,
msg);
- if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
- msg->elements[0].flags = LDB_FLAG_MOD_ADD;
- ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb,
- msg);
- }
+
assert_int_equal(ret, LDB_SUCCESS);
}
@@ -2085,7 +1986,6 @@ static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req
struct ldb_message_element *el;
TALLOC_FREE(ctx->test_ctx->ldb);
TALLOC_FREE(ctx->test_ctx->ev);
- close(pipes[0]);
ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
if (ctx->test_ctx->ev == NULL) {
exit(LDB_ERR_OPERATIONS_ERROR);
@@ -2148,7 +2048,6 @@ static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req
exit(ret);
}
- close(pipes[1]);
ret = read(pipes[0], buf, 2);
assert_int_equal(ret, 2);
@@ -2361,7 +2260,6 @@ static void test_ldb_modify_before_ldb_wait(void **state)
struct ldb_message_element *el;
TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb);
TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev);
- close(pipes[0]);
search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx);
if (search_test_ctx->ldb_test_ctx->ev == NULL) {
exit(LDB_ERR_OPERATIONS_ERROR);
@@ -2430,7 +2328,6 @@ static void test_ldb_modify_before_ldb_wait(void **state)
ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb);
exit(ret);
}
- close(pipes[1]);
ret = read(pipes[0], buf, 2);
assert_int_equal(ret, 2);
@@ -2762,7 +2659,6 @@ static int ldb_case_test_setup(void **state)
struct keyval kvs[] = {
{ "cn", "CaseInsensitiveValue" },
{ "uid", "CaseSensitiveValue" },
- { "objectUUID", "0123456789abcdef" },
{ NULL, NULL },
};
@@ -2954,14 +2850,6 @@ static void test_ldb_attrs_index_handler(void **state)
syntax, &cn_attr_2);
assert_int_equal(ret, LDB_SUCCESS);
- syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
- assert_non_null(syntax);
-
- ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
- "", 0,
- syntax, &default_attr);
- assert_int_equal(ret, LDB_SUCCESS);
-
/*
* Set an attribute handler
*/
@@ -2976,11 +2864,6 @@ static void test_ldb_attrs_index_handler(void **state)
/* Add the index (actually any modify will do) */
while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
- if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
- ldif->msg->elements[0].flags = LDB_FLAG_MOD_ADD;
- ret = ldb_modify(ldb_test_ctx->ldb,
- ldif->msg);
- }
assert_int_equal(ret, LDB_SUCCESS);
}
@@ -3066,8 +2949,7 @@ static int ldb_rename_test_setup(void **state)
add_dn_with_cn(ldb_test_ctx,
rename_test_ctx->basedn,
- "test_rename_cn_val",
- "0123456789abcde0");
+ "test_rename_cn_val");
*state = rename_test_ctx;
return 0;
@@ -3172,8 +3054,7 @@ static void test_ldb_rename_to_exists(void **state)
add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
new_dn,
- "test_rename_cn_val",
- "0123456789abcde1");
+ "test_rename_cn_val");
ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
rename_test_ctx->basedn,
@@ -3340,10 +3221,6 @@ static void test_read_only(void **state)
ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
assert_int_equal(ret, 0);
- ret = ldb_msg_add_string(msg, "objectUUID",
- "0123456789abcde1");
- assert_int_equal(ret, LDB_SUCCESS);
-
ret = ldb_add(ro_ldb, msg);
assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
TALLOC_FREE(msg);
@@ -3357,16 +3234,12 @@ static void test_read_only(void **state)
msg = ldb_msg_new(tmp_ctx);
assert_non_null(msg);
- msg->dn = ldb_dn_new_fmt(msg, rw_ldb, "dc=test");
+ msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
assert_non_null(msg->dn);
ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
assert_int_equal(ret, 0);
- ret = ldb_msg_add_string(msg, "objectUUID",
- "0123456789abcde2");
- assert_int_equal(ret, LDB_SUCCESS);
-
ret = ldb_add(rw_ldb, msg);
assert_int_equal(ret, LDB_SUCCESS);
TALLOC_FREE(msg);
@@ -3440,12 +3313,8 @@ static int ldb_unique_index_test_setup(void **state)
const char *index_ldif = \
"dn: @INDEXLIST\n"
"@IDXATTR: cn\n"
-#ifdef GUID_IDX
- "@IDXGUID: objectUUID\n"
- "@IDX_DN_GUID: GUID\n"
-#endif
"\n";
- const char *options[] = {"modules:unique_index_test", NULL};
+ const char *options[] = {"modules:unique_index_test"};
ret = ldb_register_module(&ldb_unique_index_test_module_ops);
@@ -3532,10 +3401,6 @@ static void test_ldb_add_unique_value_to_unique_index(void **state)
ret = ldb_msg_add_string(msg, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg, "objectUUID",
- "0123456789abcde1");
- assert_int_equal(ret, LDB_SUCCESS);
-
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, LDB_SUCCESS);
@@ -3550,12 +3415,8 @@ static int ldb_non_unique_index_test_setup(void **state)
const char *index_ldif = \
"dn: @INDEXLIST\n"
"@IDXATTR: cn\n"
-#ifdef GUID_IDX
- "@IDXGUID: objectUUID\n"
- "@IDX_DN_GUID: GUID\n"
-#endif
"\n";
- const char *options[] = {"modules:unique_index_test", NULL};
+ const char *options[] = {"modules:unique_index_test"};
ret = ldb_register_module(&ldb_unique_index_test_module_ops);
@@ -3624,10 +3485,6 @@ static void test_ldb_add_duplicate_value_to_unique_index(void **state)
ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg01, "objectUUID",
- "0123456789abcde1");
- assert_int_equal(ret, LDB_SUCCESS);
-
ret = ldb_add(test_ctx->ldb, msg01);
assert_int_equal(ret, LDB_SUCCESS);
@@ -3640,10 +3497,6 @@ static void test_ldb_add_duplicate_value_to_unique_index(void **state)
ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg02, "objectUUID",
- "0123456789abcde2");
- assert_int_equal(ret, LDB_SUCCESS);
-
ret = ldb_add(test_ctx->ldb, msg02);
assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
talloc_free(tmp_ctx);
@@ -3673,9 +3526,6 @@ static void test_ldb_add_to_index_duplicates_allowed(void **state)
ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg01, "objectUUID",
- "0123456789abcde1");
-
ret = ldb_add(test_ctx->ldb, msg01);
assert_int_equal(ret, LDB_SUCCESS);
@@ -3688,9 +3538,6 @@ static void test_ldb_add_to_index_duplicates_allowed(void **state)
ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg02, "objectUUID",
- "0123456789abcde2");
-
ret = ldb_add(test_ctx->ldb, msg02);
assert_int_equal(ret, LDB_SUCCESS);
talloc_free(tmp_ctx);
@@ -3720,9 +3567,6 @@ static void test_ldb_add_to_index_unique_values_required(void **state)
ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg01, "objectUUID",
- "0123456789abcde1");
-
ret = ldb_add(test_ctx->ldb, msg01);
assert_int_equal(ret, LDB_SUCCESS);
@@ -3735,9 +3579,6 @@ static void test_ldb_add_to_index_unique_values_required(void **state)
ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg02, "objectUUID",
- "0123456789abcde2");
-
ret = ldb_add(test_ctx->ldb, msg02);
assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
talloc_free(tmp_ctx);
@@ -3763,11 +3604,6 @@ static void test_ldb_unique_index_duplicate_logging(void **state)
char *debug_string = NULL;
char *p = NULL;
- /* The GUID mode is not compatible with this test */
-#ifdef GUID_IDX
- return;
-#endif
-
ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
tmp_ctx = talloc_new(test_ctx);
assert_non_null(tmp_ctx);
@@ -3781,9 +3617,6 @@ static void test_ldb_unique_index_duplicate_logging(void **state)
ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg01, "objectUUID",
- "0123456789abcde1");
-
ret = ldb_add(test_ctx->ldb, msg01);
assert_int_equal(ret, LDB_SUCCESS);
@@ -3796,9 +3629,6 @@ static void test_ldb_unique_index_duplicate_logging(void **state)
ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg02, "objectUUID",
- "0123456789abcde2");
-
ret = ldb_add(test_ctx->ldb, msg02);
assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
@@ -3823,11 +3653,6 @@ static void test_ldb_duplicate_dn_logging(void **state)
TALLOC_CTX *tmp_ctx;
char *debug_string = NULL;
- /* The GUID mode is not compatible with this test */
-#ifdef GUID_IDX
- return;
-#endif
-
ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
tmp_ctx = talloc_new(test_ctx);
assert_non_null(tmp_ctx);
@@ -3841,9 +3666,6 @@ static void test_ldb_duplicate_dn_logging(void **state)
ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg01, "objectUUID",
- "0123456789abcde1");
-
ret = ldb_add(test_ctx->ldb, msg01);
assert_int_equal(ret, LDB_SUCCESS);
@@ -3856,9 +3678,6 @@ static void test_ldb_duplicate_dn_logging(void **state)
ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
assert_int_equal(ret, LDB_SUCCESS);
- ret = ldb_msg_add_string(msg02, "objectUUID",
- "0123456789abcde2");
-
ret = ldb_add(test_ctx->ldb, msg02);
assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
@@ -4045,475 +3864,6 @@ static void test_ldb_guid_index_duplicate_dn_logging(void **state)
talloc_free(tmp_ctx);
}
-static void test_ldb_talloc_destructor_transaction_cleanup(void **state)
-{
- struct ldbtest_ctx *test_ctx = NULL;
-
- test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
- assert_non_null(test_ctx);
-
- ldb_transaction_start(test_ctx->ldb);
-
- /*
- * Trigger the destructor
- */
- TALLOC_FREE(test_ctx->ldb);
-
- /*
- * Now ensure that a new connection can be opened
- */
- {
- TALLOC_CTX *tctx = talloc_new(test_ctx);
- struct ldbtest_ctx *ctx = talloc_zero(tctx, struct ldbtest_ctx);
- struct ldb_dn *basedn;
- struct ldb_result *result = NULL;
- int ret;
-
- ldbtest_setup((void *)&ctx);
-
- basedn = ldb_dn_new_fmt(tctx, ctx->ldb, "dc=test");
- assert_non_null(basedn);
-
- ret = ldb_search(ctx->ldb,
- tctx,
- &result,
- basedn,
- LDB_SCOPE_BASE,
- NULL,
- NULL);
- assert_int_equal(ret, 0);
- assert_non_null(result);
- assert_int_equal(result->count, 0);
-
- ldbtest_teardown((void *)&ctx);
- }
-}
-
-#ifdef TEST_LMDB
-static int test_ldb_multiple_connections_callback(struct ldb_request *req,
- struct ldb_reply *ares)
-{
- int ret;
- int pipes[2];
- char buf[2];
- int pid, child_pid;
- int wstatus;
-
- switch (ares->type) {
- case LDB_REPLY_ENTRY:
- break;
-
- case LDB_REPLY_REFERRAL:
- return LDB_SUCCESS;
-
- case LDB_REPLY_DONE:
- return ldb_request_done(req, LDB_SUCCESS);
- }
-
- {
- /*
- * We open a new ldb on an ldb that is already open and
- * then close it.
- *
- * If the multiple connection wrapping is correct the
- * underlying MDB_env will be left open and we should see
- * an active reader in the child we fork next
- */
- struct ldb_context *ldb = NULL;
- struct tevent_context *ev = NULL;
- TALLOC_CTX *mem_ctx = talloc_new(NULL);
-
- ev = tevent_context_init(mem_ctx);
- assert_non_null(ev);
-
- ldb = ldb_init(mem_ctx, ev);
- assert_non_null(ldb);
-
- ret = ldb_connect(ldb, TEST_BE"://apitest.ldb" , 0, NULL);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
- TALLOC_FREE(ldb);
- TALLOC_FREE(mem_ctx);
- }
-
- ret = pipe(pipes);
- assert_int_equal(ret, 0);
-
- child_pid = fork();
- if (child_pid == 0) {
- struct MDB_env *env = NULL;
- struct MDB_envinfo stat;
- close(pipes[0]);
-
- /*
- * Check that there are exactly two readers on the MDB file
- * backing the ldb.
- *
- */
- ret = mdb_env_create(&env);
- if (ret != 0) {
- print_error(__location__
- " mdb_env_create returned (%d)",
- ret);
- exit(ret);
- }
-
- ret = mdb_env_open(env,
- "apitest.ldb",
- MDB_NOSUBDIR | MDB_NOTLS,
- 0644);
- if (ret != 0) {
- print_error(__location__
- " mdb_env_open returned (%d)",
- ret);
- exit(ret);
- }
-
- ret = mdb_env_info(env, &stat);
- if (ret != 0) {
- print_error(__location__
- " mdb_env_info returned (%d)",
- ret);
- exit(ret);
- }
- if (stat.me_numreaders != 2) {
- print_error(__location__
- " Incorrect number of readers (%d)",
- stat.me_numreaders);
- exit(LDB_ERR_CONSTRAINT_VIOLATION);
- }
-
- ret = write(pipes[1], "GO", 2);
- if (ret != 2) {
- print_error(__location__
- " write returned (%d)",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- exit(LDB_SUCCESS);
- }
- close(pipes[1]);
- ret = read(pipes[0], buf, 2);
- assert_int_equal(ret, 2);
-
- pid = waitpid(child_pid, &wstatus, 0);
- assert_int_equal(pid, child_pid);
-
- assert_true(WIFEXITED(wstatus));
-
- assert_int_equal(WEXITSTATUS(wstatus), 0);
- return LDB_SUCCESS;
-
-}
-
-static void test_ldb_close_with_multiple_connections(void **state)
-{
- struct search_test_ctx *search_test_ctx = NULL;
- struct ldb_dn *search_dn = NULL;
- struct ldb_request *req = NULL;
- int ret = 0;
-
- search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx);
- assert_non_null(search_test_ctx);
-
- search_dn = ldb_dn_new_fmt(search_test_ctx,
- search_test_ctx->ldb_test_ctx->ldb,
- "cn=test_search_cn,"
- "dc=search_test_entry");
- assert_non_null(search_dn);
-
- /*
- * The search just needs to call DONE, we don't care about the
- * contents of the search for this test
- */
- ret = ldb_build_search_req(&req,
- search_test_ctx->ldb_test_ctx->ldb,
- search_test_ctx,
- search_dn,
- LDB_SCOPE_SUBTREE,
- "(&(!(filterAttr=*))"
- "(cn=test_search_cn))",
- NULL,
- NULL,
- NULL,
- test_ldb_multiple_connections_callback,
- NULL);
- assert_int_equal(ret, 0);
-
- ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
- assert_int_equal(ret, 0);
-
- ret = ldb_wait(req->handle, LDB_WAIT_ALL);
- assert_int_equal(ret, 0);
-}
-
-#endif
-
-static void test_transaction_start_across_fork(void **state)
-{
- struct ldb_context *ldb1 = NULL;
- int ret;
- struct ldbtest_ctx *test_ctx = NULL;
- int pipes[2];
- char buf[2];
- int wstatus;
- pid_t pid, child_pid;
-
- test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
-
- /*
- * Open the database
- */
- ldb1 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
-
- ret = pipe(pipes);
- assert_int_equal(ret, 0);
-
- child_pid = fork();
- if (child_pid == 0) {
- close(pipes[0]);
- ret = ldb_transaction_start(ldb1);
- if (ret != LDB_ERR_PROTOCOL_ERROR) {
- print_error(__location__": ldb_transaction_start "
- "returned (%d) %s\n",
- ret,
- ldb1->err_string);
- exit(LDB_ERR_OTHER);
- }
-
- ret = write(pipes[1], "GO", 2);
- if (ret != 2) {
- print_error(__location__
- " write returned (%d)",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- exit(LDB_SUCCESS);
- }
- close(pipes[1]);
- ret = read(pipes[0], buf, 2);
- assert_int_equal(ret, 2);
-
- pid = waitpid(child_pid, &wstatus, 0);
- assert_int_equal(pid, child_pid);
-
- assert_true(WIFEXITED(wstatus));
-
- assert_int_equal(WEXITSTATUS(wstatus), 0);
-}
-
-static void test_transaction_commit_across_fork(void **state)
-{
- struct ldb_context *ldb1 = NULL;
- int ret;
- struct ldbtest_ctx *test_ctx = NULL;
- int pipes[2];
- char buf[2];
- int wstatus;
- pid_t pid, child_pid;
-
- test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
-
- /*
- * Open the database
- */
- ldb1 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
-
- ret = ldb_transaction_start(ldb1);
- assert_int_equal(ret, 0);
-
- ret = pipe(pipes);
- assert_int_equal(ret, 0);
-
- child_pid = fork();
- if (child_pid == 0) {
- close(pipes[0]);
- ret = ldb_transaction_commit(ldb1);
-
- if (ret != LDB_ERR_PROTOCOL_ERROR) {
- print_error(__location__": ldb_transaction_commit "
- "returned (%d) %s\n",
- ret,
- ldb1->err_string);
- exit(LDB_ERR_OTHER);
- }
-
- ret = write(pipes[1], "GO", 2);
- if (ret != 2) {
- print_error(__location__
- " write returned (%d)",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- exit(LDB_SUCCESS);
- }
- close(pipes[1]);
- ret = read(pipes[0], buf, 2);
- assert_int_equal(ret, 2);
-
- pid = waitpid(child_pid, &wstatus, 0);
- assert_int_equal(pid, child_pid);
-
- assert_true(WIFEXITED(wstatus));
-
- assert_int_equal(WEXITSTATUS(wstatus), 0);
-}
-
-static void test_lock_read_across_fork(void **state)
-{
- struct ldb_context *ldb1 = NULL;
- int ret;
- struct ldbtest_ctx *test_ctx = NULL;
- int pipes[2];
- char buf[2];
- int wstatus;
- pid_t pid, child_pid;
-
- test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
-
- /*
- * Open the database
- */
- ldb1 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
-
- ret = pipe(pipes);
- assert_int_equal(ret, 0);
-
- child_pid = fork();
- if (child_pid == 0) {
- struct ldb_dn *basedn;
- struct ldb_result *result = NULL;
-
- close(pipes[0]);
-
- basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test");
- assert_non_null(basedn);
-
- ret = ldb_search(test_ctx->ldb,
- test_ctx,
- &result,
- basedn,
- LDB_SCOPE_BASE,
- NULL,
- NULL);
- if (ret != LDB_ERR_PROTOCOL_ERROR) {
- print_error(__location__": ldb_search "
- "returned (%d) %s\n",
- ret,
- ldb1->err_string);
- exit(LDB_ERR_OTHER);
- }
-
- ret = write(pipes[1], "GO", 2);
- if (ret != 2) {
- print_error(__location__
- " write returned (%d)",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- exit(LDB_SUCCESS);
- }
- close(pipes[1]);
- ret = read(pipes[0], buf, 2);
- assert_int_equal(ret, 2);
-
- pid = waitpid(child_pid, &wstatus, 0);
- assert_int_equal(pid, child_pid);
-
- assert_true(WIFEXITED(wstatus));
-
- assert_int_equal(WEXITSTATUS(wstatus), 0);
-
- {
- /*
- * Ensure that the search actually succeeds on the opening
- * pid
- */
- struct ldb_dn *basedn;
- struct ldb_result *result = NULL;
-
- close(pipes[0]);
-
- basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test");
- assert_non_null(basedn);
-
- ret = ldb_search(test_ctx->ldb,
- test_ctx,
- &result,
- basedn,
- LDB_SCOPE_BASE,
- NULL,
- NULL);
- assert_int_equal(0, ret);
- }
-}
-
-static void test_multiple_opens_across_fork(void **state)
-{
- struct ldb_context *ldb1 = NULL;
- struct ldb_context *ldb2 = NULL;
- int ret;
- struct ldbtest_ctx *test_ctx = NULL;
- int pipes[2];
- char buf[2];
- int wstatus;
- pid_t pid, child_pid;
-
- test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
-
- /*
- * Open the database again
- */
- ldb1 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- ldb2 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb2, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
-
- ret = pipe(pipes);
- assert_int_equal(ret, 0);
-
- child_pid = fork();
- if (child_pid == 0) {
- struct ldb_context *ldb3 = NULL;
-
- close(pipes[0]);
- ldb3 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
- if (ret != 0) {
- print_error(__location__": ldb_connect returned (%d)\n",
- ret);
- exit(ret);
- }
- ret = write(pipes[1], "GO", 2);
- if (ret != 2) {
- print_error(__location__
- " write returned (%d)",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- exit(LDB_SUCCESS);
- }
- close(pipes[1]);
- ret = read(pipes[0], buf, 2);
- assert_int_equal(ret, 2);
-
- pid = waitpid(child_pid, &wstatus, 0);
- assert_int_equal(pid, child_pid);
-
- assert_true(WIFEXITED(wstatus));
-
- assert_int_equal(WEXITSTATUS(wstatus), 0);
-}
int main(int argc, const char **argv)
{
@@ -4548,9 +3898,6 @@ int main(int argc, const char **argv)
cmocka_unit_test_setup_teardown(test_transactions,
ldbtest_setup,
ldbtest_teardown),
- cmocka_unit_test_setup_teardown(test_nested_transactions,
- ldbtest_setup,
- ldbtest_teardown),
cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
ldb_modify_test_setup,
ldb_modify_test_teardown),
@@ -4669,7 +4016,6 @@ int main(int argc, const char **argv)
test_ldb_add_to_index_unique_values_required,
ldb_non_unique_index_test_setup,
ldb_non_unique_index_test_teardown),
- /* These tests are not compatible with mdb */
cmocka_unit_test_setup_teardown(
test_ldb_unique_index_duplicate_logging,
ldb_unique_index_test_setup,
@@ -4686,32 +4032,6 @@ int main(int argc, const char **argv)
test_ldb_unique_index_duplicate_with_guid,
ldb_guid_index_test_setup,
ldb_guid_index_test_teardown),
- cmocka_unit_test_setup_teardown(
- test_ldb_talloc_destructor_transaction_cleanup,
- ldbtest_setup,
- ldbtest_teardown),
-#ifdef TEST_LMDB
- cmocka_unit_test_setup_teardown(
- test_ldb_close_with_multiple_connections,
- ldb_search_test_setup,
- ldb_search_test_teardown),
-#endif
- cmocka_unit_test_setup_teardown(
- test_transaction_start_across_fork,
- ldbtest_setup,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_transaction_commit_across_fork,
- ldbtest_setup,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_lock_read_across_fork,
- ldbtest_setup,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_multiple_opens_across_fork,
- ldbtest_setup,
- ldbtest_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
diff --git a/tests/ldb_tdb_test.c b/tests/ldb_tdb_test.c
deleted file mode 100644
index 686a351..0000000
--- a/tests/ldb_tdb_test.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * lmdb backend specific tests for ldb
- *
- * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/*
- * lmdb backend specific tests for ldb
- *
- * Setup and tear down code copied from ldb_mod_op_test.c
- */
-
-/*
- * from cmocka.c:
- * These headers or their equivalents should be included prior to
- * including
- * this header file.
- *
- * #include <stdarg.h>
- * #include <stddef.h>
- * #include <setjmp.h>
- *
- * This allows test applications to use custom definitions of C standard
- * library functions and types.
- *
- */
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <errno.h>
-#include <unistd.h>
-#include <talloc.h>
-#include <tevent.h>
-#include <ldb.h>
-#include <ldb_module.h>
-#include <ldb_private.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <sys/wait.h>
-
-#include "../ldb_tdb/ldb_tdb.h"
-
-#define TEST_BE "tdb"
-
-struct ldbtest_ctx {
- struct tevent_context *ev;
- struct ldb_context *ldb;
-
- const char *dbfile;
-
- const char *dbpath;
-};
-
-static void unlink_old_db(struct ldbtest_ctx *test_ctx)
-{
- int ret;
-
- errno = 0;
- ret = unlink(test_ctx->dbfile);
- if (ret == -1 && errno != ENOENT) {
- fail();
- }
-}
-
-static int ldbtest_noconn_setup(void **state)
-{
- struct ldbtest_ctx *test_ctx;
-
- test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
- assert_non_null(test_ctx);
-
- test_ctx->ev = tevent_context_init(test_ctx);
- assert_non_null(test_ctx->ev);
-
- test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
- assert_non_null(test_ctx->ldb);
-
- test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
- assert_non_null(test_ctx->dbfile);
-
- test_ctx->dbpath = talloc_asprintf(test_ctx,
- TEST_BE"://%s", test_ctx->dbfile);
- assert_non_null(test_ctx->dbpath);
-
- unlink_old_db(test_ctx);
- *state = test_ctx;
- return 0;
-}
-
-static int ldbtest_noconn_teardown(void **state)
-{
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
-
- unlink_old_db(test_ctx);
- talloc_free(test_ctx);
- return 0;
-}
-
-static int ldbtest_setup(void **state)
-{
- struct ldbtest_ctx *test_ctx;
- int ret;
- struct ldb_ldif *ldif;
- const char *index_ldif = \
- "dn: @INDEXLIST\n"
- "@IDXGUID: objectUUID\n"
- "@IDX_DN_GUID: GUID\n"
- "\n";
-
- ldbtest_noconn_setup((void **) &test_ctx);
-
- ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
-
- while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) {
- ret = ldb_add(test_ctx->ldb, ldif->msg);
- assert_int_equal(ret, LDB_SUCCESS);
- }
- *state = test_ctx;
- return 0;
-}
-
-static int ldbtest_teardown(void **state)
-{
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
- ldbtest_noconn_teardown((void **) &test_ctx);
- return 0;
-}
-
-
-static TDB_CONTEXT *get_tdb_context(struct ldb_context *ldb)
-{
- void *data = NULL;
- struct ltdb_private *ltdb = NULL;
- TDB_CONTEXT *tdb = NULL;
-
- data = ldb_module_get_private(ldb->modules);
- assert_non_null(data);
-
- ltdb = talloc_get_type(data, struct ltdb_private);
- assert_non_null(ltdb);
-
- tdb = ltdb->tdb;
- assert_non_null(tdb);
-
- return tdb;
-}
-
-static void test_multiple_opens(void **state)
-{
- struct ldb_context *ldb1 = NULL;
- struct ldb_context *ldb2 = NULL;
- struct ldb_context *ldb3 = NULL;
- TDB_CONTEXT *tdb1 = NULL;
- TDB_CONTEXT *tdb2 = NULL;
- TDB_CONTEXT *tdb3 = NULL;
- int ret;
- struct ldbtest_ctx *test_ctx = NULL;
-
- test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
-
- /*
- * Open the database again
- */
- ldb1 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- ldb2 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- ldb3 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
- assert_int_equal(ret, 0);
- /*
- * We now have 3 ldb's open pointing to the same on disk database
- * they should all share the same MDB_env
- */
- tdb1 = get_tdb_context(ldb1);
- tdb2 = get_tdb_context(ldb2);
- tdb3 = get_tdb_context(ldb3);
-
- assert_ptr_equal(tdb1, tdb2);
- assert_ptr_equal(tdb1, tdb3);
-}
-
-static void test_multiple_opens_across_fork(void **state)
-{
- struct ldb_context *ldb1 = NULL;
- struct ldb_context *ldb2 = NULL;
- TDB_CONTEXT *tdb1 = NULL;
- TDB_CONTEXT *tdb2 = NULL;
- int ret;
- struct ldbtest_ctx *test_ctx = NULL;
- int pipes[2];
- char buf[2];
- int wstatus;
- pid_t pid, child_pid;
-
- test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
-
- /*
- * Open the database again
- */
- ldb1 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- ldb2 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- tdb1 = get_tdb_context(ldb1);
- tdb2 = get_tdb_context(ldb2);
-
- ret = pipe(pipes);
- assert_int_equal(ret, 0);
-
- child_pid = fork();
- if (child_pid == 0) {
- struct ldb_context *ldb3 = NULL;
- TDB_CONTEXT *tdb3 = NULL;
-
- close(pipes[0]);
- ldb3 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
- if (ret != 0) {
- print_error(__location__": ldb_connect returned (%d)\n",
- ret);
- exit(ret);
- }
- tdb3 = get_tdb_context(ldb3);
- if (tdb1 != tdb2) {
- print_error(__location__": tdb1 != tdb2\n");
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- if (tdb1 != tdb3) {
- print_error(__location__": tdb1 != tdb3\n");
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- ret = write(pipes[1], "GO", 2);
- if (ret != 2) {
- print_error(__location__
- " write returned (%d)",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- exit(LDB_SUCCESS);
- }
- close(pipes[1]);
- ret = read(pipes[0], buf, 2);
- assert_int_equal(ret, 2);
-
- pid = waitpid(child_pid, &wstatus, 0);
- assert_int_equal(pid, child_pid);
-
- assert_true(WIFEXITED(wstatus));
-
- assert_int_equal(WEXITSTATUS(wstatus), 0);
-}
-
-static void test_multiple_opens_across_fork_triggers_reopen(void **state)
-{
- struct ldb_context *ldb1 = NULL;
- struct ldb_context *ldb2 = NULL;
- TDB_CONTEXT *tdb1 = NULL;
- TDB_CONTEXT *tdb2 = NULL;
- int ret;
- struct ldbtest_ctx *test_ctx = NULL;
- int pipes[2];
- char buf[2];
- int wstatus;
- pid_t pid, child_pid;
-
- test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
-
- /*
- * Open the database again
- */
- ldb1 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- ldb2 = ldb_init(test_ctx, test_ctx->ev);
- ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
- assert_int_equal(ret, 0);
-
- tdb1 = get_tdb_context(ldb1);
- tdb2 = get_tdb_context(ldb2);
- assert_ptr_equal(tdb1, tdb2);
-
- /*
- * Break the internal tdb_reopen() by making a
- * transaction
- *
- * This shows that the tdb_reopen() is called, which is
- * essential if the host OS does not have pread()
- */
- ret = tdb_transaction_start(tdb1);
- assert_int_equal(ret, 0);
-
- ret = pipe(pipes);
- assert_int_equal(ret, 0);
-
- child_pid = fork();
- if (child_pid == 0) {
- struct ldb_context *ldb3 = NULL;
-
- close(pipes[0]);
- ldb3 = ldb_init(test_ctx, test_ctx->ev);
-
- /*
- * This should fail as we have taken out a lock
- * against the raw TDB above, and tdb_reopen()
- * will fail in that state.
- *
- * This check matters as tdb_reopen() is important
- * if the host does not have pread()
- */
- ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
- if (ret == 0) {
- print_error(__location__": ldb_connect expected "
- "LDB_ERR_OPERATIONS_ERROR "
- "returned (%d)\n",
- ret);
- exit(5000);
- }
- ret = write(pipes[1], "GO", 2);
- if (ret != 2) {
- print_error(__location__
- " write returned (%d)",
- ret);
- exit(LDB_ERR_OPERATIONS_ERROR);
- }
- exit(LDB_SUCCESS);
- }
- close(pipes[1]);
- ret = read(pipes[0], buf, 2);
- assert_int_equal(ret, 2);
-
- pid = waitpid(child_pid, &wstatus, 0);
- assert_int_equal(pid, child_pid);
-
- assert_true(WIFEXITED(wstatus));
-
- assert_int_equal(WEXITSTATUS(wstatus), 0);
-}
-
-int main(int argc, const char **argv)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test_setup_teardown(
- test_multiple_opens,
- ldbtest_setup,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_multiple_opens_across_fork,
- ldbtest_setup,
- ldbtest_teardown),
- cmocka_unit_test_setup_teardown(
- test_multiple_opens_across_fork_triggers_reopen,
- ldbtest_setup,
- ldbtest_teardown),
- };
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/python/api.py b/tests/python/api.py
index 9d01535..48fac88 100755
--- a/tests/python/api.py
+++ b/tests/python/api.py
@@ -15,12 +15,6 @@ PY3 = sys.version_info > (3, 0)
TDB_PREFIX = "tdb://"
MDB_PREFIX = "mdb://"
-MDB_INDEX_OBJ = {
- "dn": "@INDEXLIST",
- "@IDXONE": [b"1"],
- "@IDXGUID": [b"objectUUID"],
- "@IDX_DN_GUID": [b"GUID"]
-}
def tempdir():
import tempfile
@@ -83,10 +77,6 @@ class SimpleLdb(LdbBaseTest):
self.testdir = tempdir()
self.filename = os.path.join(self.testdir, "test.ldb")
self.ldb = ldb.Ldb(self.url(), flags=self.flags())
- try:
- self.ldb.add(self.index)
- except AttributeError:
- pass
def tearDown(self):
shutil.rmtree(self.testdir)
@@ -175,7 +165,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=foo1")
m["b"] = [b"a"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
self.assertRaises(ldb.LdbError, lambda: l.delete(m.dn, ["search_options:1:2"]))
l.delete(m.dn)
@@ -188,7 +177,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=foo3")
m["b"] = ["a"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
try:
self.assertTrue(ldb.Dn(l, "dc=foo3") in l)
@@ -217,7 +205,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=foo4")
m["bla"] = b"bla"
- m["objectUUID"] = b"0123456789abcdef"
self.assertEqual(len(l.search()), 0)
l.add(m)
try:
@@ -258,7 +245,6 @@ class SimpleLdb(LdbBaseTest):
m1 = ldb.Message()
m1.dn = ldb.Dn(l, "dc=foo4")
m1["bla"] = b"bla"
- m1["objectUUID"] = b"0123456789abcdef"
l.add(m1)
try:
s = l.search_iterator()
@@ -275,7 +261,6 @@ class SimpleLdb(LdbBaseTest):
m2 = ldb.Message()
m2.dn = ldb.Dn(l, "dc=foo5")
m2["bla"] = b"bla"
- m2["objectUUID"] = b"0123456789abcdee"
l.add(m2)
s = l.search_iterator()
@@ -332,7 +317,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=foo4")
m["bla"] = "bla"
- m["objectUUID"] = b"0123456789abcdef"
self.assertEqual(len(l.search()), 0)
l.add(m)
try:
@@ -351,8 +335,7 @@ class SimpleLdb(LdbBaseTest):
def test_add_dict(self):
l = ldb.Ldb(self.url(), flags=self.flags())
m = {"dn": ldb.Dn(l, "dc=foo5"),
- "bla": b"bla",
- "objectUUID": b"0123456789abcdef"}
+ "bla": b"bla"}
self.assertEqual(len(l.search()), 0)
l.add(m)
try:
@@ -363,8 +346,7 @@ class SimpleLdb(LdbBaseTest):
def test_add_dict_text(self):
l = ldb.Ldb(self.url(), flags=self.flags())
m = {"dn": ldb.Dn(l, "dc=foo5"),
- "bla": "bla",
- "objectUUID": b"0123456789abcdef"}
+ "bla": "bla"}
self.assertEqual(len(l.search()), 0)
l.add(m)
try:
@@ -374,8 +356,7 @@ class SimpleLdb(LdbBaseTest):
def test_add_dict_string_dn(self):
l = ldb.Ldb(self.url(), flags=self.flags())
- m = {"dn": "dc=foo6", "bla": b"bla",
- "objectUUID": b"0123456789abcdef"}
+ m = {"dn": "dc=foo6", "bla": b"bla"}
self.assertEqual(len(l.search()), 0)
l.add(m)
try:
@@ -385,8 +366,7 @@ class SimpleLdb(LdbBaseTest):
def test_add_dict_bytes_dn(self):
l = ldb.Ldb(self.url(), flags=self.flags())
- m = {"dn": b"dc=foo6", "bla": b"bla",
- "objectUUID": b"0123456789abcdef"}
+ m = {"dn": b"dc=foo6", "bla": b"bla"}
self.assertEqual(len(l.search()), 0)
l.add(m)
try:
@@ -399,7 +379,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=foo7")
m["bla"] = b"bla"
- m["objectUUID"] = b"0123456789abcdef"
self.assertEqual(len(l.search()), 0)
l.add(m)
try:
@@ -413,7 +392,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=foo8")
m["bla"] = b"bla"
- m["objectUUID"] = b"0123456789abcdef"
self.assertEqual(len(l.search()), 0)
l.add(m)
self.assertEqual(len(l.search()), 1)
@@ -423,22 +401,32 @@ class SimpleLdb(LdbBaseTest):
finally:
l.delete(ldb.Dn(l, "dc=bar"))
+ def test_rename_bad_string_dns(self):
+ l = ldb.Ldb(self.url(), flags=self.flags())
+ m = ldb.Message()
+ m.dn = ldb.Dn(l, "dc=foo8")
+ m["bla"] = b"bla"
+ m["objectUUID"] = b"0123456789abcdef"
+ self.assertEqual(len(l.search()), 0)
+ l.add(m)
+ self.assertEqual(len(l.search()), 1)
+ self.assertRaises(ldb.LdbError,lambda: l.rename("dcXfoo8", "dc=bar"))
+ self.assertRaises(ldb.LdbError,lambda: l.rename("dc=foo8", "dcXbar"))
+ l.delete(ldb.Dn(l, "dc=foo8"))
+
def test_empty_dn(self):
l = ldb.Ldb(self.url(), flags=self.flags())
self.assertEqual(0, len(l.search()))
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=empty")
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
rm = l.search()
self.assertEqual(1, len(rm))
- self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]),
- set(rm[0].keys()))
+ self.assertEqual(set(["dn", "distinguishedName"]), set(rm[0].keys()))
rm = l.search(m.dn)
self.assertEqual(1, len(rm))
- self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]),
- set(rm[0].keys()))
+ self.assertEqual(set(["dn", "distinguishedName"]), set(rm[0].keys()))
rm = l.search(m.dn, attrs=["blah"])
self.assertEqual(1, len(rm))
self.assertEqual(0, len(rm[0]))
@@ -448,7 +436,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=modifydelete")
m["bla"] = [b"1234"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
rm = l.search(m.dn)[0]
self.assertEqual([b"1234"], list(rm["bla"]))
@@ -460,8 +447,7 @@ class SimpleLdb(LdbBaseTest):
l.modify(m)
rm = l.search(m.dn)
self.assertEqual(1, len(rm))
- self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]),
- set(rm[0].keys()))
+ self.assertEqual(set(["dn", "distinguishedName"]), set(rm[0].keys()))
rm = l.search(m.dn, attrs=["bla"])
self.assertEqual(1, len(rm))
self.assertEqual(0, len(rm[0]))
@@ -473,7 +459,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=modifydelete")
m.text["bla"] = ["1234"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
rm = l.search(m.dn)[0]
self.assertEqual(["1234"], list(rm.text["bla"]))
@@ -485,8 +470,7 @@ class SimpleLdb(LdbBaseTest):
l.modify(m)
rm = l.search(m.dn)
self.assertEqual(1, len(rm))
- self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]),
- set(rm[0].keys()))
+ self.assertEqual(set(["dn", "distinguishedName"]), set(rm[0].keys()))
rm = l.search(m.dn, attrs=["bla"])
self.assertEqual(1, len(rm))
self.assertEqual(0, len(rm[0]))
@@ -498,7 +482,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=add")
m["bla"] = [b"1234"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
try:
m = ldb.Message()
@@ -507,7 +490,7 @@ class SimpleLdb(LdbBaseTest):
self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags())
l.modify(m)
rm = l.search(m.dn)[0]
- self.assertEqual(3, len(rm))
+ self.assertEqual(2, len(rm))
self.assertEqual([b"1234", b"456"], list(rm["bla"]))
finally:
l.delete(ldb.Dn(l, "dc=add"))
@@ -517,7 +500,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=add")
m.text["bla"] = ["1234"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
try:
m = ldb.Message()
@@ -526,7 +508,7 @@ class SimpleLdb(LdbBaseTest):
self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags())
l.modify(m)
rm = l.search(m.dn)[0]
- self.assertEqual(3, len(rm))
+ self.assertEqual(2, len(rm))
self.assertEqual(["1234", "456"], list(rm.text["bla"]))
finally:
l.delete(ldb.Dn(l, "dc=add"))
@@ -536,7 +518,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=modify2")
m["bla"] = [b"1234", b"456"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
try:
m = ldb.Message()
@@ -545,7 +526,7 @@ class SimpleLdb(LdbBaseTest):
self.assertEqual(ldb.FLAG_MOD_REPLACE, m["bla"].flags())
l.modify(m)
rm = l.search(m.dn)[0]
- self.assertEqual(3, len(rm))
+ self.assertEqual(2, len(rm))
self.assertEqual([b"789"], list(rm["bla"]))
rm = l.search(m.dn, attrs=["bla"])[0]
self.assertEqual(1, len(rm))
@@ -557,7 +538,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=modify2")
m.text["bla"] = ["1234", "456"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
try:
m = ldb.Message()
@@ -566,7 +546,7 @@ class SimpleLdb(LdbBaseTest):
self.assertEqual(ldb.FLAG_MOD_REPLACE, m["bla"].flags())
l.modify(m)
rm = l.search(m.dn)[0]
- self.assertEqual(3, len(rm))
+ self.assertEqual(2, len(rm))
self.assertEqual(["789"], list(rm.text["bla"]))
rm = l.search(m.dn, attrs=["bla"])[0]
self.assertEqual(1, len(rm))
@@ -578,7 +558,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=add")
m["bla"] = [b"1234"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
try:
m = ldb.Message()
@@ -587,7 +566,7 @@ class SimpleLdb(LdbBaseTest):
self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags())
l.modify(m)
rm = l.search(m.dn)[0]
- self.assertEqual(3, len(rm))
+ self.assertEqual(2, len(rm))
self.assertEqual([b"1234", b"456"], list(rm["bla"]))
# Now create another modify, but switch the flags before we do it
@@ -605,7 +584,6 @@ class SimpleLdb(LdbBaseTest):
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=add")
m.text["bla"] = ["1234"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
try:
m = ldb.Message()
@@ -614,7 +592,7 @@ class SimpleLdb(LdbBaseTest):
self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags())
l.modify(m)
rm = l.search(m.dn)[0]
- self.assertEqual(3, len(rm))
+ self.assertEqual(2, len(rm))
self.assertEqual(["1234", "456"], list(rm.text["bla"]))
# Now create another modify, but switch the flags before we do it
@@ -632,7 +610,6 @@ class SimpleLdb(LdbBaseTest):
l.transaction_start()
m = ldb.Message(ldb.Dn(l, "dc=foo9"))
m["foo"] = [b"bar"]
- m["objectUUID"] = b"0123456789abcdef"
l.add(m)
l.transaction_commit()
l.delete(m.dn)
@@ -642,7 +619,6 @@ class SimpleLdb(LdbBaseTest):
l.transaction_start()
m = ldb.Message(ldb.Dn(l, "dc=foo10"))
m["foo"] = [b"bar"]
- m["objectUUID"] = b"0123456789abcdee"
l.add(m)
l.transaction_cancel()
self.assertEqual(0, len(l.search(ldb.Dn(l, "dc=foo10"))))
@@ -662,7 +638,6 @@ class SimpleLdb(LdbBaseTest):
"cN" : b"LDAPtestUSER",
"givenname" : b"ldap",
"displayname" : b"foo\0bar",
- "objectUUID" : b"0123456789abcdef"
})
res = l.search(expression="(dn=dc=somedn)")
self.assertEqual(b"foo\0bar", res[0]["displayname"][0])
@@ -671,17 +646,6 @@ class SimpleLdb(LdbBaseTest):
l = ldb.Ldb(self.url(), flags=self.flags())
self.assertRaises(ldb.LdbError,lambda: l.search("", ldb.SCOPE_SUBTREE, "&(dc=*)(dn=*)", ["dc"]))
-# Run the SimpleLdb tests against an lmdb backend
-class SimpleLdbLmdb(SimpleLdb):
-
- def setUp(self):
- self.prefix = MDB_PREFIX
- self.index = MDB_INDEX_OBJ
- super(SimpleLdbLmdb, self).setUp()
-
- def tearDown(self):
- super(SimpleLdbLmdb, self).tearDown()
-
class SearchTests(LdbBaseTest):
def tearDown(self):
shutil.rmtree(self.testdir)
@@ -716,7 +680,7 @@ class SearchTests(LdbBaseTest):
self.l.add({"dn": "DC=SAMBA,DC=ORG",
"name": b"samba.org",
- "objectUUID": b"0123456789abcdef"})
+ "objectUUID": b"0123456789abcddf"})
self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG",
"name": b"Admins",
"x": "z", "y": "a",
@@ -1192,17 +1156,109 @@ class SearchTests(LdbBaseTest):
# At some point we should fix this, but it isn't trivial
self.assertEqual(len(res11), 1)
+ def test_distinguishedName_filter_one(self):
+ """Testing that a distinguishedName= filter succeeds
+ when the scope is SCOPE_ONELEVEL.
-# Run the search tests against an lmdb backend
-class SearchTestsLmdb(SearchTests):
+ This should be made more consistent, but for now lock in
+ the behaviour
- def setUp(self):
- self.prefix = MDB_PREFIX
- self.index = MDB_INDEX_OBJ
- super(SearchTestsLmdb, self).setUp()
+ """
- def tearDown(self):
- super(SearchTestsLmdb, self).tearDown()
+ res11 = self.l.search(base="DC=SAMBA,DC=ORG",
+ scope=ldb.SCOPE_ONELEVEL,
+ expression="(distinguishedName=OU=OU1,DC=SAMBA,DC=ORG)")
+ self.assertEqual(len(res11), 1)
+
+ def test_distinguishedName_filter_subtree(self):
+ """Testing that a distinguishedName= filter succeeds
+ when the scope is SCOPE_SUBTREE"""
+
+ res11 = self.l.search(base="DC=SAMBA,DC=ORG",
+ scope=ldb.SCOPE_SUBTREE,
+ expression="(distinguishedName=OU=OU1,DC=SAMBA,DC=ORG)")
+ self.assertEqual(len(res11), 1)
+
+ def test_distinguishedName_filter_base(self):
+ """Testing that (incorrectly) a distinguishedName= filter works
+ when the scope is SCOPE_BASE"""
+
+ res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG",
+ scope=ldb.SCOPE_BASE,
+ expression="(distinguishedName=OU=OU1,DC=SAMBA,DC=ORG)")
+
+ # At some point we should fix this, but it isn't trivial
+ self.assertEqual(len(res11), 1)
+
+ def test_bad_dn_filter_base(self):
+ """Testing that a dn= filter on an invalid DN works
+ when the scope is SCOPE_BASE but
+ returns zero results"""
+
+ res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG",
+ scope=ldb.SCOPE_BASE,
+ expression="(dn=OU=OU1,DC=SAMBA,DCXXXX)")
+
+ # At some point we should fix this, but it isn't trivial
+ self.assertEqual(len(res11), 0)
+
+
+ def test_bad_dn_filter_one(self):
+ """Testing that a dn= filter succeeds but returns zero
+ results when the DN is not valid on a SCOPE_ONELEVEL search
+
+ """
+
+ res11 = self.l.search(base="DC=SAMBA,DC=ORG",
+ scope=ldb.SCOPE_ONELEVEL,
+ expression="(dn=OU=OU1,DC=SAMBA,DCXXXX)")
+ self.assertEqual(len(res11), 0)
+
+ def test_bad_dn_filter_subtree(self):
+ """Testing that a dn= filter succeeds but returns zero
+ results when the DN is not valid on a SCOPE_SUBTREE search
+
+ """
+
+ res11 = self.l.search(base="DC=SAMBA,DC=ORG",
+ scope=ldb.SCOPE_SUBTREE,
+ expression="(dn=OU=OU1,DC=SAMBA,DCXXXX)")
+ self.assertEqual(len(res11), 0)
+
+ def test_bad_distinguishedName_filter_base(self):
+ """Testing that a distinguishedName= filter on an invalid DN works
+ when the scope is SCOPE_BASE but
+ returns zero results"""
+
+ res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG",
+ scope=ldb.SCOPE_BASE,
+ expression="(distinguishedName=OU=OU1,DC=SAMBA,DCXXXX)")
+
+ # At some point we should fix this, but it isn't trivial
+ self.assertEqual(len(res11), 0)
+
+
+ def test_bad_distinguishedName_filter_one(self):
+ """Testing that a distinguishedName= filter succeeds but returns zero
+ results when the DN is not valid on a SCOPE_ONELEVEL search
+
+ """
+
+ res11 = self.l.search(base="DC=SAMBA,DC=ORG",
+ scope=ldb.SCOPE_ONELEVEL,
+ expression="(distinguishedName=OU=OU1,DC=SAMBA,DCXXXX)")
+ self.assertEqual(len(res11), 0)
+
+ def test_bad_distinguishedName_filter_subtree(self):
+ """Testing that a distinguishedName= filter succeeds but returns zero
+ results when the DN is not valid on a SCOPE_SUBTREE search
+
+ """
+
+ res11 = self.l.search(base="DC=SAMBA,DC=ORG",
+ scope=ldb.SCOPE_SUBTREE,
+ expression="(distinguishedName=OU=OU1,DC=SAMBA,DCXXXX)")
+ self.assertEqual(len(res11), 0)
class IndexedSearchTests(SearchTests):
@@ -1271,12 +1327,12 @@ class GUIDIndexedSearchTests(SearchTests):
"""Test searches using the index, to ensure the index doesn't
break things"""
def setUp(self):
- self.index = {"dn": "@INDEXLIST",
- "@IDXATTR": [b"x", b"y", b"ou"],
- "@IDXGUID": [b"objectUUID"],
- "@IDX_DN_GUID": [b"GUID"]}
super(GUIDIndexedSearchTests, self).setUp()
+ self.l.add({"dn": "@INDEXLIST",
+ "@IDXATTR": [b"x", b"y", b"ou"],
+ "@IDXGUID": [b"objectUUID"],
+ "@IDX_DN_GUID": [b"GUID"]})
self.IDXGUID = True
self.IDXONE = True
@@ -1285,14 +1341,15 @@ class GUIDIndexedDNFilterSearchTests(SearchTests):
"""Test searches using the index, to ensure the index doesn't
break things"""
def setUp(self):
- self.index = {"dn": "@INDEXLIST",
- "@IDXATTR": [b"x", b"y", b"ou"],
- "@IDXGUID": [b"objectUUID"],
- "@IDX_DN_GUID": [b"GUID"]}
super(GUIDIndexedDNFilterSearchTests, self).setUp()
self.l.add({"dn": "@OPTIONS",
"disallowDNFilter": "TRUE"})
self.disallowDNFilter = True
+
+ self.l.add({"dn": "@INDEXLIST",
+ "@IDXATTR": [b"x", b"y", b"ou"],
+ "@IDXGUID": [b"objectUUID"],
+ "@IDX_DN_GUID": [b"GUID"]})
self.IDX = True
self.IDXGUID = True
@@ -1300,47 +1357,20 @@ class GUIDAndOneLevelIndexedSearchTests(SearchTests):
"""Test searches using the index including @IDXONE, to ensure
the index doesn't break things"""
def setUp(self):
- self.index = {"dn": "@INDEXLIST",
- "@IDXATTR": [b"x", b"y", b"ou"],
- "@IDXGUID": [b"objectUUID"],
- "@IDX_DN_GUID": [b"GUID"]}
super(GUIDAndOneLevelIndexedSearchTests, self).setUp()
self.l.add({"dn": "@OPTIONS",
"disallowDNFilter": "TRUE"})
self.disallowDNFilter = True
+
+ self.l.add({"dn": "@INDEXLIST",
+ "@IDXATTR": [b"x", b"y", b"ou"],
+ "@IDXONE": [b"1"],
+ "@IDXGUID": [b"objectUUID"],
+ "@IDX_DN_GUID": [b"GUID"]})
self.IDX = True
self.IDXGUID = True
self.IDXONE = True
-class GUIDIndexedSearchTestsLmdb(GUIDIndexedSearchTests):
-
- def setUp(self):
- self.prefix = MDB_PREFIX
- super(GUIDIndexedSearchTestsLmdb, self).setUp()
-
- def tearDown(self):
- super(GUIDIndexedSearchTestsLmdb, self).tearDown()
-
-
-class GUIDIndexedDNFilterSearchTestsLmdb(GUIDIndexedDNFilterSearchTests):
-
- def setUp(self):
- self.prefix = MDB_PREFIX
- super(GUIDIndexedDNFilterSearchTestsLmdb, self).setUp()
-
- def tearDown(self):
- super(GUIDIndexedDNFilterSearchTestsLmdb, self).tearDown()
-
-
-class GUIDAndOneLevelIndexedSearchTestsLmdb(GUIDAndOneLevelIndexedSearchTests):
-
- def setUp(self):
- self.prefix = MDB_PREFIX
- super(GUIDAndOneLevelIndexedSearchTestsLmdb, self).setUp()
-
- def tearDown(self):
- super(GUIDAndOneLevelIndexedSearchTestsLmdb, self).tearDown()
-
class AddModifyTests(LdbBaseTest):
def tearDown(self):
@@ -1357,11 +1387,6 @@ class AddModifyTests(LdbBaseTest):
self.l = ldb.Ldb(self.url(),
flags=self.flags(),
options=["modules:rdn_name"])
- try:
- self.l.add(self.index)
- except AttributeError:
- pass
-
self.l.add({"dn": "DC=SAMBA,DC=ORG",
"name": b"samba.org",
"objectUUID": b"0123456789abcdef"})
@@ -1383,6 +1408,17 @@ class AddModifyTests(LdbBaseTest):
enum = err.args[0]
self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS)
+ def test_add_bad(self):
+ try:
+ self.l.add({"dn": "BAD,DC=SAMBA,DC=ORG",
+ "name": b"Admins",
+ "x": "z", "y": "a",
+ "objectUUID": b"0123456789abcde1"})
+ self.fail("Should have failed adding entry with invalid DN")
+ except ldb.LdbError as err:
+ enum = err.args[0]
+ self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX)
+
def test_add_del_add(self):
self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
"name": b"Admins",
@@ -1415,19 +1451,6 @@ class AddModifyTests(LdbBaseTest):
"name": b"Admins",
"x": "z", "y": "a",
"objectUUID": b"0123456789abcde2"})
-
- res2 = self.l.search(base="DC=SAMBA,DC=ORG",
- scope=ldb.SCOPE_SUBTREE,
- expression="(objectUUID=0123456789abcde1)")
- self.assertEqual(len(res2), 1)
- self.assertEqual(str(res2[0].dn), "OU=DUP,DC=SAMBA,DC=ORG")
-
- res3 = self.l.search(base="DC=SAMBA,DC=ORG",
- scope=ldb.SCOPE_SUBTREE,
- expression="(objectUUID=0123456789abcde2)")
- self.assertEqual(len(res3), 1)
- self.assertEqual(str(res3[0].dn), "OU=DUP2,DC=SAMBA,DC=ORG")
-
try:
self.l.rename("OU=DUP,DC=SAMBA,DC=ORG",
"OU=DUP2,DC=SAMBA,DC=ORG")
@@ -1477,6 +1500,34 @@ class AddModifyTests(LdbBaseTest):
enum = err.args[0]
self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT)
+ def test_move_bad(self):
+ self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG",
+ "name": b"Admins",
+ "x": "z", "y": "a",
+ "objectUUID": b"0123456789abcde2"})
+
+ try:
+ self.l.rename("OUXDUP,DC=SAMBA,DC=ORG",
+ "OU=DUP2,DC=SAMBA,DC=ORG")
+ self.fail("Should have failed on invalid DN")
+ except ldb.LdbError as err:
+ enum = err.args[0]
+ self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX)
+
+ def test_move_bad2(self):
+ self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG",
+ "name": b"Admins",
+ "x": "z", "y": "a",
+ "objectUUID": b"0123456789abcde2"})
+
+ try:
+ self.l.rename("OU=DUP,DC=SAMBA,DC=ORG",
+ "OUXDUP2,DC=SAMBA,DC=ORG")
+ self.fail("Should have failed on missing")
+ except ldb.LdbError as err:
+ enum = err.args[0]
+ self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX)
+
def test_move_fail_move_add(self):
self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
"name": b"Admins",
@@ -1503,25 +1554,14 @@ class AddModifyTests(LdbBaseTest):
"objectUUID": b"0123456789abcde3"})
-class AddModifyTestsLmdb(AddModifyTests):
-
- def setUp(self):
- self.prefix = MDB_PREFIX
- self.index = MDB_INDEX_OBJ
- super(AddModifyTestsLmdb, self).setUp()
-
- def tearDown(self):
- super(AddModifyTestsLmdb, self).tearDown()
-
class IndexedAddModifyTests(AddModifyTests):
"""Test searches using the index, to ensure the index doesn't
break things"""
def setUp(self):
- if not hasattr(self, 'index'):
- self.index = {"dn": "@INDEXLIST",
- "@IDXATTR": [b"x", b"y", b"ou", b"objectUUID"],
- "@IDXONE": [b"1"]}
super(IndexedAddModifyTests, self).setUp()
+ self.l.add({"dn": "@INDEXLIST",
+ "@IDXATTR": [b"x", b"y", b"ou", b"objectUUID"],
+ "@IDXONE": [b"1"]})
def test_duplicate_GUID(self):
try:
@@ -1595,12 +1635,14 @@ class GUIDIndexedAddModifyTests(IndexedAddModifyTests):
"""Test searches using the index, to ensure the index doesn't
break things"""
def setUp(self):
- self.index = {"dn": "@INDEXLIST",
- "@IDXATTR": [b"x", b"y", b"ou"],
- "@IDXONE": [b"1"],
- "@IDXGUID": [b"objectUUID"],
- "@IDX_DN_GUID": [b"GUID"]}
super(GUIDIndexedAddModifyTests, self).setUp()
+ indexlist = {"dn": "@INDEXLIST",
+ "@IDXATTR": [b"x", b"y", b"ou"],
+ "@IDXONE": [b"1"],
+ "@IDXGUID": [b"objectUUID"],
+ "@IDX_DN_GUID": [b"GUID"]}
+ m = ldb.Message.from_dict(self.l, indexlist, ldb.FLAG_MOD_REPLACE)
+ self.l.modify(m)
class GUIDTransIndexedAddModifyTests(GUIDIndexedAddModifyTests):
@@ -1623,23 +1665,6 @@ class TransIndexedAddModifyTests(IndexedAddModifyTests):
self.l.transaction_commit()
super(TransIndexedAddModifyTests, self).tearDown()
-class GuidIndexedAddModifyTestsLmdb(GUIDIndexedAddModifyTests):
-
- def setUp(self):
- self.prefix = MDB_PREFIX
- super(GuidIndexedAddModifyTestsLmdb, self).setUp()
-
- def tearDown(self):
- super(GuidIndexedAddModifyTestsLmdb, self).tearDown()
-
-class GuidTransIndexedAddModifyTestsLmdb(GUIDTransIndexedAddModifyTests):
-
- def setUp(self):
- self.prefix = MDB_PREFIX
- super(GuidTransIndexedAddModifyTestsLmdb, self).setUp()
-
- def tearDown(self):
- super(GuidTransIndexedAddModifyTestsLmdb, self).tearDown()
class BadIndexTests(LdbBaseTest):
def setUp(self):
@@ -1800,6 +1825,7 @@ class GUIDBadIndexTests(BadIndexTests):
super(GUIDBadIndexTests, self).setUp()
+
class DnTests(TestCase):
def setUp(self):
@@ -1933,11 +1959,9 @@ class DnTests(TestCase):
dn3 = ldb.Dn(self.ldb, "cn=bar,dc=base")
dn4 = ldb.Dn(self.ldb, "cn=baz,cn=bar,dc=base")
- self.assertTrue(dn1.is_child_of(dn1))
self.assertTrue(dn2.is_child_of(dn1))
self.assertTrue(dn4.is_child_of(dn1))
self.assertTrue(dn4.is_child_of(dn3))
- self.assertTrue(dn4.is_child_of(dn4))
self.assertFalse(dn3.is_child_of(dn2))
self.assertFalse(dn1.is_child_of(dn4))
@@ -1953,11 +1977,9 @@ class DnTests(TestCase):
dn3 = ldb.Dn(self.ldb, dn3_str)
dn4 = ldb.Dn(self.ldb, dn4_str)
- self.assertTrue(dn1.is_child_of(dn1_str))
self.assertTrue(dn2.is_child_of(dn1_str))
self.assertTrue(dn4.is_child_of(dn1_str))
self.assertTrue(dn4.is_child_of(dn3_str))
- self.assertTrue(dn4.is_child_of(dn4_str))
self.assertFalse(dn3.is_child_of(dn2_str))
self.assertFalse(dn1.is_child_of(dn4_str))
@@ -2139,13 +2161,13 @@ class LdbMsgTests(TestCase):
self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO")
self.msg["foo"] = [b"bla"]
self.msg["bar"] = [b"bla"]
- self.assertEqual(["dn", "foo", "bar"], list(self.msg.keys()))
+ self.assertEqual(["dn", "foo", "bar"], self.msg.keys())
def test_keys_text(self):
self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO")
self.msg["foo"] = ["bla"]
self.msg["bar"] = ["bla"]
- self.assertEqual(["dn", "foo", "bar"], list(self.msg.text.keys()))
+ self.assertEqual(["dn", "foo", "bar"], self.msg.text.keys())
def test_dn(self):
self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO")
@@ -2417,36 +2439,19 @@ class LdbResultTests(LdbBaseTest):
self.testdir = tempdir()
self.filename = os.path.join(self.testdir, "test.ldb")
self.l = ldb.Ldb(self.url(), flags=self.flags())
- try:
- self.l.add(self.index)
- except AttributeError:
- pass
- self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": b"samba.org",
- "objectUUID": b"0123456789abcde0"})
- self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b"Admins",
- "objectUUID": b"0123456789abcde1"})
- self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": b"Users",
- "objectUUID": b"0123456789abcde2"})
- self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": b"OU #1",
- "objectUUID": b"0123456789abcde3"})
- self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": b"OU #2",
- "objectUUID": b"0123456789abcde4"})
- self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": b"OU #3",
- "objectUUID": b"0123456789abcde5"})
- self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": b"OU #4",
- "objectUUID": b"0123456789abcde6"})
- self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": b"OU #5",
- "objectUUID": b"0123456789abcde7"})
- self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": b"OU #6",
- "objectUUID": b"0123456789abcde8"})
- self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": b"OU #7",
- "objectUUID": b"0123456789abcde9"})
- self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": b"OU #8",
- "objectUUID": b"0123456789abcdea"})
- self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": b"OU #9",
- "objectUUID": b"0123456789abcdeb"})
- self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": b"OU #10",
- "objectUUID": b"0123456789abcdec"})
+ self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": b"samba.org"})
+ self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b"Admins"})
+ self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": b"Users"})
+ self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": b"OU #1"})
+ self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": b"OU #2"})
+ self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": b"OU #3"})
+ self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": b"OU #4"})
+ self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": b"OU #5"})
+ self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": b"OU #6"})
+ self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": b"OU #7"})
+ self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": b"OU #8"})
+ self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": b"OU #9"})
+ self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": b"OU #10"})
def tearDown(self):
shutil.rmtree(self.testdir)
@@ -2547,8 +2552,7 @@ class LdbResultTests(LdbBaseTest):
# write to it
child_ldb.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG",
- "name": b"samba.org",
- "objectUUID": b"o123456789acbdef"})
+ "name": b"samba.org"})
os.write(w1, b"added")
@@ -2619,8 +2623,7 @@ class LdbResultTests(LdbBaseTest):
# write to it
child_ldb.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG",
- "name": b"samba.org",
- "objectUUID": b"o123456789acbdef"})
+ "name": b"samba.org"})
os.write(w1, b"added")
@@ -2680,17 +2683,6 @@ class LdbResultTests(LdbBaseTest):
self.assertEqual(got_pid, pid)
-class LdbResultTestsLmdb(LdbResultTests):
-
- def setUp(self):
- self.prefix = MDB_PREFIX
- self.index = MDB_INDEX_OBJ
- super(LdbResultTestsLmdb, self).setUp()
-
- def tearDown(self):
- super(LdbResultTestsLmdb, self).tearDown()
-
-
class BadTypeTests(TestCase):
def test_control(self):
l = ldb.Ldb()
diff --git a/tests/python/index.py b/tests/python/index.py
index 2613a4d..d8a84f2 100755
--- a/tests/python/index.py
+++ b/tests/python/index.py
@@ -17,10 +17,15 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-"""Tests for truncated index keys
+"""Tests for index keys
-Databases such as lmdb have a maximum key length, these tests ensure that
-ldb behaves correctly in those circumstances.
+This is a modified version of the test from master for databases such
+as lmdb have a maximum key length, instead just checking that the
+GUID index code still operates correctly.
+
+Many of the test names are therefore incorrect, but are retained
+to keep the code easy to backport into if more tested are added in
+master.
"""
@@ -113,42 +118,19 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
super(MaxIndexKeyLengthTests, self).setUp()
self.testdir = tempdir()
self.filename = os.path.join(self.testdir, "key_len_test.ldb")
- # Note that the maximum key length is set to 54
- # This accounts for the 4 bytes added by the dn formatting
- # a leading dn=, and a trailing zero terminator
- #
+ # Note that the maximum key length is set to 50
self.l = ldb.Ldb(self.url(),
options=[
"modules:rdn_name",
- "max_key_len_for_self_test:54"])
+ "max_key_len_for_self_test:50"])
self.l.add({"dn": "@ATTRIBUTES",
"uniqueThing": "UNIQUE_INDEX"})
self.l.add({"dn": "@INDEXLIST",
- "@IDXATTR": [
- b"uniqueThing",
- b"notUnique",
- b"base64____lt",
- b"base64_____eq",
- b"base64______gt"],
+ "@IDXATTR": [b"uniqueThing", b"notUnique"],
"@IDXONE": [b"1"],
"@IDXGUID": [b"objectUUID"],
"@IDX_DN_GUID": [b"GUID"]})
- # Add a value to a unique index that exceeds the maximum key length
- # This should be rejected.
- def test_add_long_unique_add(self):
- try:
- self.l.add({"dn": "OU=UNIQUE_MAX_LEN,DC=SAMBA,DC=ORG",
- "objectUUID": b"0123456789abcdef",
- "uniqueThing": "01234567890123456789012345678901"})
- # index key will be
- # "@INDEX:UNIQUETHING:01234567890123456789012345678901"
- self.fail("Should have failed on long index key")
-
- except ldb.LdbError as err:
- enum = err.args[0]
- self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION)
-
# Test that DN's longer the maximum key length can be added
# and that duplicate DN's are rejected correctly
def test_add_long_dn_add(self):
@@ -158,21 +140,12 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
#
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG",
"objectUUID": b"0123456789abcdef"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM",
"objectUUID": b"0123456789abcde0"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcde0" + b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV",
"objectUUID": b"0123456789abcde1"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcde0" + b"0123456789abcde1" + b"0123456789abcdef")
# Key is equal to max length does not get inserted into the truncated
# key namespace
@@ -232,23 +205,13 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
# @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG",
"objectUUID": b"0123456789abcdef"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM",
"objectUUID": b"0123456789abcde0"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcde0" + b"0123456789abcdef")
# Non conflicting rename, should succeed
self.l.rename("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG",
"OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV")
- # Index should be unchanged.
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcde0" + b"0123456789abcdef")
# Conflicting rename should fail
try:
@@ -267,15 +230,9 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
#
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG",
"objectUUID": b"0123456789abcdef"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV",
"objectUUID": b"0123456789abcde1"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcde1" + b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
"objectUUID": b"0123456789abcde5"})
@@ -305,9 +262,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
# Check the indexes are correct
self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcde1" + b"0123456789abcdef")
- self.checkGuids(
"@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
b"0123456789abcde5")
@@ -328,9 +282,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
# Check the indexes are correct
self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcde1")
- self.checkGuids(
"@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
b"0123456789abcde5")
@@ -346,9 +297,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
self.assertEqual(len(res), 1)
# Check the indexes are correct
self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- None)
- self.checkGuids(
"@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
b"0123456789abcde5")
@@ -371,15 +319,9 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
#
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG",
"objectUUID": b"0123456789abcdef"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV",
"objectUUID": b"0123456789abcde1"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcde1" + b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
"objectUUID": b"0123456789abcde5"})
@@ -415,15 +357,9 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
#
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG",
"objectUUID": b"0123456789abcdef"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV",
"objectUUID": b"0123456789abcde1"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcde1" + b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
"objectUUID": b"0123456789abcde5"})
@@ -470,33 +406,21 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
"objectUUID": b"0123456789abcdef"})
self.l.add({"dn": "OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2",
"objectUUID": b"0123456789abcd1f"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR",
- b"0123456789abcd1f" + b"0123456789abcdef")
self.l.add({"dn": "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1",
"objectUUID": b"0123456789abcde1"})
self.l.add({"dn": "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2",
"objectUUID": b"0123456789abcd11"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA",
- b"0123456789abcd11" + b"0123456789abcde1")
self.l.add({"dn": "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1",
"objectUUID": b"0123456789abcde2"})
self.l.add({"dn": "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2",
"objectUUID": b"0123456789abcdf2"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA",
- b"0123456789abcde2" + b"0123456789abcdf2")
self.l.add({"dn": "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1",
"objectUUID": b"0123456789abcde3"})
self.l.add({"dn": "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2",
"objectUUID": b"0123456789abcd13"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA",
- b"0123456789abcd13" + b"0123456789abcde3")
# This key is not truncated as it's the max_key_len
self.l.add({"dn": "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA",
@@ -547,40 +471,25 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
"objectUUID": b"0123456789abcde4"})
self.l.add({"dn": "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR3",
"objectUUID": b"0123456789abcde8"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR",
- b"0123456789abcde4" + b"0123456789abcde8" + b"0123456789abcdef")
self.l.add({"dn": "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1",
"objectUUID": b"0123456789abcde1"})
self.l.add({"dn": "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2",
"objectUUID": b"0123456789abcde5"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA",
- b"0123456789abcde1" + b"0123456789abcde5")
self.l.add({"dn": "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1",
"objectUUID": b"0123456789abcde2"})
self.l.add({"dn": "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2",
"objectUUID": b"0123456789abcde6"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA",
- b"0123456789abcde2" + b"0123456789abcde6")
self.l.add({"dn": "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1",
"objectUUID": b"0123456789abcde3"})
self.l.add({"dn": "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2",
"objectUUID": b"0123456789abcde7"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA",
- b"0123456789abcde3" + b"0123456789abcde7")
self.l.add({"dn": "OU=04,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR4",
"objectUUID": b"0123456789abcde9"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=04,OU=A_LONG_DN_SUB_TREE,DC=SAMBA",
- b"0123456789abcde9")
res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1",
scope=ldb.SCOPE_SUBTREE)
@@ -627,15 +536,9 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
#
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG",
"objectUUID": b"0123456789abcdef"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV",
"objectUUID": b"0123456789abcde1"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
- b"0123456789abcde1" + b"0123456789abcdef")
self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA",
"objectUUID": b"0123456789abcde5"})
@@ -719,29 +622,18 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
self.l.add({"dn": "OU=03,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG",
"notUnique": gt_max,
"objectUUID": b"0123456789abcde2"})
- # But in the truncated key space
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde2")
# Key longer than max so should get truncated to same key as
# the previous entries but differs in the chars after max length
self.l.add({"dn": "OU=23,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG",
"notUnique": gt_max_b,
"objectUUID": b"0123456789abcd22"})
- # But in the truncated key space
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcd22" + b"0123456789abcde2")
#
# An entry outside the tree
#
self.l.add({"dn": "OU=11,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG",
"notUnique": gt_max,
"objectUUID": b"0123456789abcd12"})
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcd12" + b"0123456789abcd22" + b"0123456789abcde2")
# Key shorter than max
#
@@ -875,36 +767,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
contains(res, "OU=12,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG"))
#
- # Test index key truncation for base64 encoded values
- #
- def test_index_truncated_base64_encoded_keys(self):
- value = b"aaaaaaaaaaaaaaaaaaaa\x02"
- # base64 encodes to "YWFhYWFhYWFhYWFhYWFhYWFhYWEC"
-
- # One less than max key length
- self.l.add({"dn": "OU=01,OU=BASE64,DC=SAMBA,DC=ORG",
- "base64____lt": value,
- "objectUUID": b"0123456789abcde0"})
- self.checkGuids(
- "@INDEX:BASE64____LT::YWFhYWFhYWFhYWFhYWFhYWFhYWEC",
- b"0123456789abcde0")
-
- # Equal max key length
- self.l.add({"dn": "OU=02,OU=BASE64,DC=SAMBA,DC=ORG",
- "base64_____eq": value,
- "objectUUID": b"0123456789abcde1"})
- self.checkGuids(
- "@INDEX:BASE64_____EQ::YWFhYWFhYWFhYWFhYWFhYWFhYWEC",
- b"0123456789abcde1")
-
- # One greater than max key length
- self.l.add({"dn": "OU=03,OU=BASE64,DC=SAMBA,DC=ORG",
- "base64______gt": value,
- "objectUUID": b"0123456789abcde2"})
- self.checkGuids(
- "@INDEX#BASE64______GT##YWFhYWFhYWFhYWFhYWFhYWFhYWE",
- b"0123456789abcde2")
- #
# Test adding to non unique index with identical multivalued index
# attributes
#
@@ -940,12 +802,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
self.l.add({"dn": "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG",
"notUnique": [aa_gt_max, ab_gt_max, bb_gt_max],
"objectUUID": b"0123456789abcde0"})
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde0" + b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- b"0123456789abcde0")
expression = "(notUnique=" + aa_gt_max.decode('ascii') + ")"
res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG",
@@ -992,16 +848,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
self.l.add({"dn": "OU=02,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG",
"notUnique": [aa_gt_max, ab_gt_max, cc_gt_max],
"objectUUID": b"0123456789abcde1"})
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde0" + b"0123456789abcde0" +
- b"0123456789abcde1" + b"0123456789abcde1")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc",
- b"0123456789abcde1")
res = self.l.search(
base="DC=SAMBA,DC=ORG",
@@ -1013,26 +859,8 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
contains(res, "OU=02,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG"))
self.l.delete("OU=02,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde0" + b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc",
- None)
self.l.delete("OU=01,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- None)
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- None)
- self.checkGuids(
- "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc",
- None)
#
# Test modification of records with non unique index with multivalued index
@@ -1054,21 +882,11 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
self.l.add({"dn": "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG",
"notUnique": [aa_gt_max, ab_gt_max, cc_gt_max],
"objectUUID": b"0123456789abcde1"})
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde0" + b"0123456789abcde0" +
- b"0123456789abcde1" + b"0123456789abcde1")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc",
- b"0123456789abcde1")
res = self.l.search(
base="DC=SAMBA,DC=ORG",
expression="(notUnique=" + aa_gt_max.decode("ascii") + ")")
- self.assertEqual(2, len(res))
+ self.assertEquals(2, len(res))
self.assertTrue(
contains(res, "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG"))
self.assertTrue(
@@ -1088,16 +906,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
# As the modify is replacing the attribute with the same contents
# there should be no changes to the indexes.
#
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde0" + b"0123456789abcde0" +
- b"0123456789abcde1" + b"0123456789abcde1")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc",
- b"0123456789abcde1")
#
# Modify that removes a value from the indexed attribute
@@ -1110,17 +918,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
"notUnique")
self.l.modify(msg)
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde0" +
- b"0123456789abcde1" + b"0123456789abcde1")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc",
- b"0123456789abcde1")
-
#
# Modify that does a constrained delete the indexed attribute
#
@@ -1132,16 +929,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
"notUnique")
self.l.modify(msg)
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde0" + b"0123456789abcde1")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc",
- b"0123456789abcde1")
-
#
# Modify that does an unconstrained delete the indexed attribute
#
@@ -1153,16 +940,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
"notUnique")
self.l.modify(msg)
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc",
- None)
-
#
# Modify that adds a value to the indexed attribute
#
@@ -1174,16 +951,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
"notUnique")
self.l.modify(msg)
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc",
- b"0123456789abcde1")
-
#
# Modify that adds a values to the indexed attribute
#
@@ -1195,17 +962,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
"notUnique")
self.l.modify(msg)
- self.checkGuids(
- "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- b"0123456789abcde0" +
- b"0123456789abcde1" + b"0123456789abcde1")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
- b"0123456789abcde0")
- self.checkGuids(
- "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc",
- b"0123456789abcde1")
-
#
# Test Sub tree searches when checkBaseOnSearch is enabled and the
# DN indexes are truncated and collide.
@@ -1228,9 +984,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
"objectUUID": b"0123456789abcdef"})
self.l.add({"dn": "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2",
"objectUUID": b"0123456789abcdee"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR",
- b"0123456789abcdee" + b"0123456789abcdef")
self.l.add({"dn": "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1",
"objectUUID": b"0123456789abcdec"})
@@ -1238,9 +991,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
"objectUUID": b"0123456789abcdeb"})
self.l.add({"dn": "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR3",
"objectUUID": b"0123456789abcded"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA",
- b"0123456789abcdeb" + b"0123456789abcdec" + b"0123456789abcded")
self.l.add({"dn": "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1",
"objectUUID": b"0123456789abcde0"})
@@ -1248,9 +998,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
"objectUUID": b"0123456789abcde1"})
self.l.add({"dn": "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR3",
"objectUUID": b"0123456789abcde2"})
- self.checkGuids(
- "@INDEX#@IDXDN#OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA",
- b"0123456789abcde0" + b"0123456789abcde1" + b"0123456789abcde2")
res = self.l.search(base="OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1",
scope=ldb.SCOPE_SUBTREE)
@@ -1280,49 +1027,6 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
code = e.args[0]
self.assertEqual(ldb.ERR_NO_SUCH_OBJECT, code)
-
-# Run the index truncation tests against an lmdb backend
-class MaxIndexKeyLengthTestsLmdb(MaxIndexKeyLengthTests):
-
- def setUp(self):
- self.prefix = MDB_PREFIX
- super(MaxIndexKeyLengthTestsLmdb, self).setUp()
-
- def tearDown(self):
- super(MaxIndexKeyLengthTestsLmdb, self).tearDown()
-
-
-# Run the index truncation tests against an lmdb backend
-class RejectSubDBIndex(LdbBaseTest):
-
- def setUp(self):
- self.prefix = MDB_PREFIX
- super(RejectSubDBIndex, self).setUp()
- self.testdir = tempdir()
- self.filename = os.path.join(self.testdir,
- "reject_subidx_test.ldb")
- self.l = ldb.Ldb(self.url(),
- options=[
- "modules:rdn_name"])
-
- def tearDown(self):
- super(RejectSubDBIndex, self).tearDown()
-
- def test_try_subdb_index(self):
- try:
- self.l.add({"dn": "@INDEXLIST",
- "@IDX_LMDB_SUBDB": [b"1"],
- "@IDXONE": [b"1"],
- "@IDXONE": [b"1"],
- "@IDXGUID": [b"objectUUID"],
- "@IDX_DN_GUID": [b"GUID"],
- })
- except ldb.LdbError as e:
- code = e.args[0]
- string = e.args[1]
- self.assertEqual(ldb.ERR_OPERATIONS_ERROR, code)
- self.assertIn("sub-database index", string)
-
if __name__ == '__main__':
import unittest
unittest.TestProgram()
diff --git a/tests/test_ldb_qsort.c b/tests/test_ldb_qsort.c
deleted file mode 100644
index 06e80d9..0000000
--- a/tests/test_ldb_qsort.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- *
- * Copyright (C) 2018 Andreas Schneider <asn@samba.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <ldb.h>
-
-static int cmp_integer(int *a, int *b, void *opaque)
-{
- if (a == NULL || b == NULL) {
- return 0;
- }
-
- if (*a > *b) {
- return 1;
- }
-
- if (*a < *b) {
- return -1;
- }
-
- return 0;
-}
-
-static void test_ldb_qsort(void **state)
-{
- int a[6] = { 6, 3, 2, 7, 9, 4 };
-
- ldb_qsort(a, 6, sizeof(int), NULL, (ldb_qsort_cmp_fn_t)cmp_integer);
-
- assert_int_equal(a[0], 2);
- assert_int_equal(a[1], 3);
- assert_int_equal(a[2], 4);
- assert_int_equal(a[3], 6);
- assert_int_equal(a[4], 7);
- assert_int_equal(a[5], 9);
-}
-
-int main(void) {
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_ldb_qsort),
- };
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/third_party/cmocka/cmocka.c b/third_party/cmocka/cmocka.c
index 0861c2c..14b2765 100644
--- a/third_party/cmocka/cmocka.c
+++ b/third_party/cmocka/cmocka.c
@@ -45,7 +45,7 @@
#include <time.h>
/*
- * This allows one to add a platform specific header file. Some embedded platforms
+ * This allows to add a platform specific header file. Some embedded platforms
* sometimes miss certain types and definitions.
*
* Example:
@@ -244,8 +244,8 @@ static void free_symbol_map_value(
static void remove_always_return_values(ListNode * const map_head,
const size_t number_of_symbol_names);
-static size_t check_for_leftover_values_list(const ListNode * head,
- const char * const error_message);
+static int check_for_leftover_values_list(const ListNode * head,
+ const char * const error_message);
static int check_for_leftover_values(
const ListNode * const map_head, const char * const error_message,
@@ -811,11 +811,11 @@ static void remove_always_return_values(ListNode * const map_head,
}
}
-static size_t check_for_leftover_values_list(const ListNode * head,
- const char * const error_message)
+static int check_for_leftover_values_list(const ListNode * head,
+ const char * const error_message)
{
ListNode *child_node;
- size_t leftover_count = 0;
+ int leftover_count = 0;
if (!list_empty(head))
{
for (child_node = head->next; child_node != head;
@@ -1952,10 +1952,10 @@ static const ListNode* check_point_allocated_blocks(void) {
/* Display the blocks allocated after the specified check point. This
* function returns the number of blocks displayed. */
-static size_t display_allocated_blocks(const ListNode * const check_point) {
+static int display_allocated_blocks(const ListNode * const check_point) {
const ListNode * const head = get_allocated_blocks_list();
const ListNode *node;
- size_t allocated_blocks = 0;
+ int allocated_blocks = 0;
assert_non_null(check_point);
assert_non_null(check_point->next);
@@ -1964,14 +1964,14 @@ static size_t display_allocated_blocks(const ListNode * const check_point) {
(const MallocBlockInfo*)node->value;
assert_non_null(block_info);
- if (allocated_blocks == 0) {
+ if (!allocated_blocks) {
cm_print_error("Blocks allocated...\n");
}
cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
block_info->location.file,
block_info->location.line,
block_info->block);
- allocated_blocks++;
+ allocated_blocks ++;
}
return allocated_blocks;
}
@@ -1997,10 +1997,10 @@ static void free_allocated_blocks(const ListNode * const check_point) {
/* Fail if any any blocks are allocated after the specified check point. */
static void fail_if_blocks_allocated(const ListNode * const check_point,
const char * const test_name) {
- const size_t allocated_blocks = display_allocated_blocks(check_point);
- if (allocated_blocks > 0) {
+ const int allocated_blocks = display_allocated_blocks(check_point);
+ if (allocated_blocks) {
free_allocated_blocks(check_point);
- cm_print_error("ERROR: %s leaked %zu block(s)\n", test_name,
+ cm_print_error("ERROR: %s leaked %d block(s)\n", test_name,
allocated_blocks);
exit_test(1);
}
diff --git a/third_party/cmocka/cmocka.h b/third_party/cmocka/cmocka.h
index 4fd82a9..72d6ae2 100644
--- a/third_party/cmocka/cmocka.h
+++ b/third_party/cmocka/cmocka.h
@@ -2269,7 +2269,7 @@ enum cm_message_output {
/**
* @brief Function to set the output format for a test.
*
- * The output format for the test can either be set globally using this
+ * The ouput format for the test can either be set globally using this
* function or overriden with environment variable CMOCKA_MESSAGE_OUTPUT.
*
* The environment variable can be set to either STDOUT, SUBUNIT, TAP or XML.
diff --git a/third_party/popt/README b/third_party/popt/README
index c66432d..95f8f8d 100644
--- a/third_party/popt/README
+++ b/third_party/popt/README
@@ -1,16 +1,18 @@
-This is the popt(3) command line option parsing library. While it is similiar
+This is the popt command line option parsing library. While it is similiar
to getopt(3), it contains a number of enhancements, including:
1) popt is fully reentrant
2) popt can parse arbitrary argv[] style arrays while
- getopt(3) makes this quite difficult
+ getopt(2) makes this quite difficult
3) popt allows users to alias command line arguments
4) popt provides convience functions for parsing strings
into argv[] style arrays
-Complete documentation on popt(3) is available in popt.ps (included in this
+popt is used by rpm, the Red Hat install program, and many other Red Hat
+utilities, all of which provide excellent examples of how to use popt.
+Complete documentation on popt is available in popt.ps (included in this
tarball), which is excerpted with permission from the book "Linux
Application Development" by Michael K. Johnson and Erik Troan (available
from Addison Wesley in May, 1998).
-Comments on popt should be addressed to popt-devel@rpm5.org.
+Comments on popt should be addressed to ewt@redhat.com.
diff --git a/third_party/popt/dummy.in b/third_party/popt/dummy.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/popt/dummy.in
diff --git a/third_party/popt/findme.c b/third_party/popt/findme.c
new file mode 100644
index 0000000..b28981b
--- /dev/null
+++ b/third_party/popt/findme.c
@@ -0,0 +1,50 @@
+/** \ingroup popt
+ * \file popt/findme.c
+ */
+
+/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
+ file accompanying popt source distributions, available from
+ ftp://ftp.rpm.org/pub/rpm/dist. */
+
+#include "system.h"
+#include "findme.h"
+
+const char * findProgramPath(const char * argv0) {
+ char * path = getenv("PATH");
+ char * pathbuf;
+ char * start, * chptr;
+ char * buf;
+
+ if (argv0 == NULL) return NULL; /* XXX can't happen */
+ /* If there is a / in the argv[0], it has to be an absolute path */
+ if (strchr(argv0, '/'))
+ return xstrdup(argv0);
+
+ if (path == NULL) return NULL;
+
+ start = pathbuf = (char *)alloca(strlen(path) + 1);
+ buf = (char *)malloc(strlen(path) + strlen(argv0) + sizeof("/"));
+ if (buf == NULL) return NULL; /* XXX can't happen */
+ strcpy(pathbuf, path);
+
+ chptr = NULL;
+ /*@-branchstate@*/
+ do {
+ if ((chptr = strchr(start, ':')))
+ *chptr = '\0';
+ sprintf(buf, "%s/%s", start, argv0);
+
+ if (!access(buf, X_OK))
+ return buf;
+
+ if (chptr)
+ start = chptr + 1;
+ else
+ start = NULL;
+ } while (start && *start);
+ /*@=branchstate@*/
+
+ free(buf);
+
+ return NULL;
+}
diff --git a/third_party/popt/lookup3.c b/third_party/popt/lookup3.c
deleted file mode 100644
index eb4e5ce..0000000
--- a/third_party/popt/lookup3.c
+++ /dev/null
@@ -1,969 +0,0 @@
-/* -------------------------------------------------------------------- */
-/*
- * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
- *
- * These are functions for producing 32-bit hashes for hash table lookup.
- * jlu32w(), jlu32l(), jlu32lpair(), jlu32b(), _JLU3_MIX(), and _JLU3_FINAL()
- * are externally useful functions. Routines to test the hash are included
- * if SELF_TEST is defined. You can use this free for any purpose. It's in
- * the public domain. It has no warranty.
- *
- * You probably want to use jlu32l(). jlu32l() and jlu32b()
- * hash byte arrays. jlu32l() is is faster than jlu32b() on
- * little-endian machines. Intel and AMD are little-endian machines.
- * On second thought, you probably want jlu32lpair(), which is identical to
- * jlu32l() except it returns two 32-bit hashes for the price of one.
- * You could implement jlu32bpair() if you wanted but I haven't bothered here.
- *
- * If you want to find a hash of, say, exactly 7 integers, do
- * a = i1; b = i2; c = i3;
- * _JLU3_MIX(a,b,c);
- * a += i4; b += i5; c += i6;
- * _JLU3_MIX(a,b,c);
- * a += i7;
- * _JLU3_FINAL(a,b,c);
- * then use c as the hash value. If you have a variable size array of
- * 4-byte integers to hash, use jlu32w(). If you have a byte array (like
- * a character string), use jlu32l(). If you have several byte arrays, or
- * a mix of things, see the comments above jlu32l().
- *
- * Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
- * then mix those integers. This is fast (you can do a lot more thorough
- * mixing with 12*3 instructions on 3 integers than you can with 3 instructions
- * on 1 byte), but shoehorning those bytes into integers efficiently is messy.
-*/
-/* -------------------------------------------------------------------- */
-
-#include <stdint.h>
-
-#if defined(_JLU3_SELFTEST)
-# define _JLU3_jlu32w 1
-# define _JLU3_jlu32l 1
-# define _JLU3_jlu32lpair 1
-# define _JLU3_jlu32b 1
-#endif
-
-/*@-redef@*/
-/*@unchecked@*/
-static const union _dbswap {
- const uint32_t ui;
- const unsigned char uc[4];
-} endian = { .ui = 0x11223344 };
-# define HASH_LITTLE_ENDIAN (endian.uc[0] == (unsigned char) 0x44)
-# define HASH_BIG_ENDIAN (endian.uc[0] == (unsigned char) 0x11)
-/*@=redef@*/
-
-#ifndef ROTL32
-# define ROTL32(x, s) (((x) << (s)) | ((x) >> (32 - (s))))
-#endif
-
-/* NOTE: The _size parameter should be in bytes. */
-#define _JLU3_INIT(_h, _size) (0xdeadbeef + ((uint32_t)(_size)) + (_h))
-
-/* -------------------------------------------------------------------- */
-/*
- * _JLU3_MIX -- mix 3 32-bit values reversibly.
- *
- * This is reversible, so any information in (a,b,c) before _JLU3_MIX() is
- * still in (a,b,c) after _JLU3_MIX().
- *
- * If four pairs of (a,b,c) inputs are run through _JLU3_MIX(), or through
- * _JLU3_MIX() in reverse, there are at least 32 bits of the output that
- * are sometimes the same for one pair and different for another pair.
- * This was tested for:
- * * pairs that differed by one bit, by two bits, in any combination
- * of top bits of (a,b,c), or in any combination of bottom bits of
- * (a,b,c).
- * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
- * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
- * is commonly produced by subtraction) look like a single 1-bit
- * difference.
- * * the base values were pseudorandom, all zero but one bit set, or
- * all zero plus a counter that starts at zero.
- *
- * Some k values for my "a-=c; a^=ROTL32(c,k); c+=b;" arrangement that
- * satisfy this are
- * 4 6 8 16 19 4
- * 9 15 3 18 27 15
- * 14 9 3 7 17 3
- * Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
- * for "differ" defined as + with a one-bit base and a two-bit delta. I
- * used http://burtleburtle.net/bob/hash/avalanche.html to choose
- * the operations, constants, and arrangements of the variables.
- *
- * This does not achieve avalanche. There are input bits of (a,b,c)
- * that fail to affect some output bits of (a,b,c), especially of a. The
- * most thoroughly mixed value is c, but it doesn't really even achieve
- * avalanche in c.
- *
- * This allows some parallelism. Read-after-writes are good at doubling
- * the number of bits affected, so the goal of mixing pulls in the opposite
- * direction as the goal of parallelism. I did what I could. Rotates
- * seem to cost as much as shifts on every machine I could lay my hands
- * on, and rotates are much kinder to the top and bottom bits, so I used
- * rotates.
- */
-/* -------------------------------------------------------------------- */
-#define _JLU3_MIX(a,b,c) \
-{ \
- a -= c; a ^= ROTL32(c, 4); c += b; \
- b -= a; b ^= ROTL32(a, 6); a += c; \
- c -= b; c ^= ROTL32(b, 8); b += a; \
- a -= c; a ^= ROTL32(c,16); c += b; \
- b -= a; b ^= ROTL32(a,19); a += c; \
- c -= b; c ^= ROTL32(b, 4); b += a; \
-}
-
-/* -------------------------------------------------------------------- */
-/**
- * _JLU3_FINAL -- final mixing of 3 32-bit values (a,b,c) into c
- *
- * Pairs of (a,b,c) values differing in only a few bits will usually
- * produce values of c that look totally different. This was tested for
- * * pairs that differed by one bit, by two bits, in any combination
- * of top bits of (a,b,c), or in any combination of bottom bits of
- * (a,b,c).
- * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
- * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
- * is commonly produced by subtraction) look like a single 1-bit
- * difference.
- * * the base values were pseudorandom, all zero but one bit set, or
- * all zero plus a counter that starts at zero.
- *
- * These constants passed:
- * 14 11 25 16 4 14 24
- * 12 14 25 16 4 14 24
- * and these came close:
- * 4 8 15 26 3 22 24
- * 10 8 15 26 3 22 24
- * 11 8 15 26 3 22 24
- */
-/* -------------------------------------------------------------------- */
-#define _JLU3_FINAL(a,b,c) \
-{ \
- c ^= b; c -= ROTL32(b,14); \
- a ^= c; a -= ROTL32(c,11); \
- b ^= a; b -= ROTL32(a,25); \
- c ^= b; c -= ROTL32(b,16); \
- a ^= c; a -= ROTL32(c,4); \
- b ^= a; b -= ROTL32(a,14); \
- c ^= b; c -= ROTL32(b,24); \
-}
-
-#if defined(_JLU3_jlu32w)
-uint32_t jlu32w(uint32_t h, /*@null@*/ const uint32_t *k, size_t size)
- /*@*/;
-/* -------------------------------------------------------------------- */
-/**
- * This works on all machines. To be useful, it requires
- * -- that the key be an array of uint32_t's, and
- * -- that the size be the number of uint32_t's in the key
- *
- * The function jlu32w() is identical to jlu32l() on little-endian
- * machines, and identical to jlu32b() on big-endian machines,
- * except that the size has to be measured in uint32_ts rather than in
- * bytes. jlu32l() is more complicated than jlu32w() only because
- * jlu32l() has to dance around fitting the key bytes into registers.
- *
- * @param h the previous hash, or an arbitrary value
- * @param *k the key, an array of uint32_t values
- * @param size the size of the key, in uint32_ts
- * @return the lookup3 hash
- */
-/* -------------------------------------------------------------------- */
-uint32_t jlu32w(uint32_t h, const uint32_t *k, size_t size)
-{
- uint32_t a = _JLU3_INIT(h, (size * sizeof(*k)));
- uint32_t b = a;
- uint32_t c = a;
-
- if (k == NULL)
- goto exit;
-
- /*----------------------------------------------- handle most of the key */
- while (size > 3) {
- a += k[0];
- b += k[1];
- c += k[2];
- _JLU3_MIX(a,b,c);
- size -= 3;
- k += 3;
- }
-
- /*----------------------------------------- handle the last 3 uint32_t's */
- switch (size) {
- case 3 : c+=k[2];
- case 2 : b+=k[1];
- case 1 : a+=k[0];
- _JLU3_FINAL(a,b,c);
- /*@fallthrough@*/
- case 0:
- break;
- }
- /*---------------------------------------------------- report the result */
-exit:
- return c;
-}
-#endif /* defined(_JLU3_jlu32w) */
-
-#if defined(_JLU3_jlu32l)
-uint32_t jlu32l(uint32_t h, const void *key, size_t size)
- /*@*/;
-/* -------------------------------------------------------------------- */
-/*
- * jlu32l() -- hash a variable-length key into a 32-bit value
- * h : can be any 4-byte value
- * k : the key (the unaligned variable-length array of bytes)
- * size : the size of the key, counting by bytes
- * Returns a 32-bit value. Every bit of the key affects every bit of
- * the return value. Two keys differing by one or two bits will have
- * totally different hash values.
- *
- * The best hash table sizes are powers of 2. There is no need to do
- * mod a prime (mod is sooo slow!). If you need less than 32 bits,
- * use a bitmask. For example, if you need only 10 bits, do
- * h = (h & hashmask(10));
- * In which case, the hash table should have hashsize(10) elements.
- *
- * If you are hashing n strings (uint8_t **)k, do it like this:
- * for (i=0, h=0; i<n; ++i) h = jlu32l(h, k[i], len[i]);
- *
- * By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
- * code any way you wish, private, educational, or commercial. It's free.
- *
- * Use for hash table lookup, or anything where one collision in 2^^32 is
- * acceptable. Do NOT use for cryptographic purposes.
- *
- * @param h the previous hash, or an arbitrary value
- * @param *k the key, an array of uint8_t values
- * @param size the size of the key
- * @return the lookup3 hash
- */
-/* -------------------------------------------------------------------- */
-uint32_t jlu32l(uint32_t h, const void *key, size_t size)
-{
- union { const void *ptr; size_t i; } u;
- uint32_t a = _JLU3_INIT(h, size);
- uint32_t b = a;
- uint32_t c = a;
-
- if (key == NULL)
- goto exit;
-
- u.ptr = key;
- if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
- const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
-#ifdef VALGRIND
- const uint8_t *k8;
-#endif
-
- /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
- while (size > 12) {
- a += k[0];
- b += k[1];
- c += k[2];
- _JLU3_MIX(a,b,c);
- size -= 12;
- k += 3;
- }
-
- /*------------------------- handle the last (probably partial) block */
- /*
- * "k[2]&0xffffff" actually reads beyond the end of the string, but
- * then masks off the part it's not allowed to read. Because the
- * string is aligned, the masked-off tail is in the same word as the
- * rest of the string. Every machine with memory protection I've seen
- * does it on word boundaries, so is OK with this. But VALGRIND will
- * still catch it and complain. The masking trick does make the hash
- * noticably faster for short strings (like English words).
- */
-#ifndef VALGRIND
-
- switch (size) {
- case 12: c += k[2]; b+=k[1]; a+=k[0]; break;
- case 11: c += k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
- case 10: c += k[2]&0xffff; b+=k[1]; a+=k[0]; break;
- case 9: c += k[2]&0xff; b+=k[1]; a+=k[0]; break;
- case 8: b += k[1]; a+=k[0]; break;
- case 7: b += k[1]&0xffffff; a+=k[0]; break;
- case 6: b += k[1]&0xffff; a+=k[0]; break;
- case 5: b += k[1]&0xff; a+=k[0]; break;
- case 4: a += k[0]; break;
- case 3: a += k[0]&0xffffff; break;
- case 2: a += k[0]&0xffff; break;
- case 1: a += k[0]&0xff; break;
- case 0: goto exit;
- }
-
-#else /* make valgrind happy */
-
- k8 = (const uint8_t *)k;
- switch (size) {
- case 12: c += k[2]; b+=k[1]; a+=k[0] break;
- case 11: c += ((uint32_t)k8[10])<<16; /*@fallthrough@*/
- case 10: c += ((uint32_t)k8[9])<<8; /*@fallthrough@*/
- case 9: c += k8[8]; /*@fallthrough@*/
- case 8: b += k[1]; a+=k[0]; break;
- case 7: b += ((uint32_t)k8[6])<<16; /*@fallthrough@*/
- case 6: b += ((uint32_t)k8[5])<<8; /*@fallthrough@*/
- case 5: b += k8[4]; /*@fallthrough@*/
- case 4: a += k[0]; break;
- case 3: a += ((uint32_t)k8[2])<<16; /*@fallthrough@*/
- case 2: a += ((uint32_t)k8[1])<<8; /*@fallthrough@*/
- case 1: a += k8[0]; break;
- case 0: goto exit;
- }
-
-#endif /* !valgrind */
-
- } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
- const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
- const uint8_t *k8;
-
- /*----------- all but last block: aligned reads and different mixing */
- while (size > 12) {
- a += k[0] + (((uint32_t)k[1])<<16);
- b += k[2] + (((uint32_t)k[3])<<16);
- c += k[4] + (((uint32_t)k[5])<<16);
- _JLU3_MIX(a,b,c);
- size -= 12;
- k += 6;
- }
-
- /*------------------------- handle the last (probably partial) block */
- k8 = (const uint8_t *)k;
- switch (size) {
- case 12:
- c += k[4]+(((uint32_t)k[5])<<16);
- b += k[2]+(((uint32_t)k[3])<<16);
- a += k[0]+(((uint32_t)k[1])<<16);
- break;
- case 11:
- c += ((uint32_t)k8[10])<<16;
- /*@fallthrough@*/
- case 10:
- c += (uint32_t)k[4];
- b += k[2]+(((uint32_t)k[3])<<16);
- a += k[0]+(((uint32_t)k[1])<<16);
- break;
- case 9:
- c += (uint32_t)k8[8];
- /*@fallthrough@*/
- case 8:
- b += k[2]+(((uint32_t)k[3])<<16);
- a += k[0]+(((uint32_t)k[1])<<16);
- break;
- case 7:
- b += ((uint32_t)k8[6])<<16;
- /*@fallthrough@*/
- case 6:
- b += (uint32_t)k[2];
- a += k[0]+(((uint32_t)k[1])<<16);
- break;
- case 5:
- b += (uint32_t)k8[4];
- /*@fallthrough@*/
- case 4:
- a += k[0]+(((uint32_t)k[1])<<16);
- break;
- case 3:
- a += ((uint32_t)k8[2])<<16;
- /*@fallthrough@*/
- case 2:
- a += (uint32_t)k[0];
- break;
- case 1:
- a += (uint32_t)k8[0];
- break;
- case 0:
- goto exit;
- }
-
- } else { /* need to read the key one byte at a time */
- const uint8_t *k = (const uint8_t *)key;
-
- /*----------- all but the last block: affect some 32 bits of (a,b,c) */
- while (size > 12) {
- a += (uint32_t)k[0];
- a += ((uint32_t)k[1])<<8;
- a += ((uint32_t)k[2])<<16;
- a += ((uint32_t)k[3])<<24;
- b += (uint32_t)k[4];
- b += ((uint32_t)k[5])<<8;
- b += ((uint32_t)k[6])<<16;
- b += ((uint32_t)k[7])<<24;
- c += (uint32_t)k[8];
- c += ((uint32_t)k[9])<<8;
- c += ((uint32_t)k[10])<<16;
- c += ((uint32_t)k[11])<<24;
- _JLU3_MIX(a,b,c);
- size -= 12;
- k += 12;
- }
-
- /*---------------------------- last block: affect all 32 bits of (c) */
- switch (size) {
- case 12: c += ((uint32_t)k[11])<<24; /*@fallthrough@*/
- case 11: c += ((uint32_t)k[10])<<16; /*@fallthrough@*/
- case 10: c += ((uint32_t)k[9])<<8; /*@fallthrough@*/
- case 9: c += (uint32_t)k[8]; /*@fallthrough@*/
- case 8: b += ((uint32_t)k[7])<<24; /*@fallthrough@*/
- case 7: b += ((uint32_t)k[6])<<16; /*@fallthrough@*/
- case 6: b += ((uint32_t)k[5])<<8; /*@fallthrough@*/
- case 5: b += (uint32_t)k[4]; /*@fallthrough@*/
- case 4: a += ((uint32_t)k[3])<<24; /*@fallthrough@*/
- case 3: a += ((uint32_t)k[2])<<16; /*@fallthrough@*/
- case 2: a += ((uint32_t)k[1])<<8; /*@fallthrough@*/
- case 1: a += (uint32_t)k[0];
- break;
- case 0:
- goto exit;
- }
- }
-
- _JLU3_FINAL(a,b,c);
-
-exit:
- return c;
-}
-#endif /* defined(_JLU3_jlu32l) */
-
-#if defined(_JLU3_jlu32lpair)
-/**
- * jlu32lpair: return 2 32-bit hash values.
- *
- * This is identical to jlu32l(), except it returns two 32-bit hash
- * values instead of just one. This is good enough for hash table
- * lookup with 2^^64 buckets, or if you want a second hash if you're not
- * happy with the first, or if you want a probably-unique 64-bit ID for
- * the key. *pc is better mixed than *pb, so use *pc first. If you want
- * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
- *
- * @param h the previous hash, or an arbitrary value
- * @param *key the key, an array of uint8_t values
- * @param size the size of the key in bytes
- * @retval *pc, IN: primary initval, OUT: primary hash
- * *retval *pb IN: secondary initval, OUT: secondary hash
- */
-void jlu32lpair(const void *key, size_t size, uint32_t *pc, uint32_t *pb)
-{
- union { const void *ptr; size_t i; } u;
- uint32_t a = _JLU3_INIT(*pc, size);
- uint32_t b = a;
- uint32_t c = a;
-
- if (key == NULL)
- goto exit;
-
- c += *pb; /* Add the secondary hash. */
-
- u.ptr = key;
- if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
- const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
-#ifdef VALGRIND
- const uint8_t *k8;
-#endif
-
- /*-- all but last block: aligned reads and affect 32 bits of (a,b,c) */
- while (size > (size_t)12) {
- a += k[0];
- b += k[1];
- c += k[2];
- _JLU3_MIX(a,b,c);
- size -= 12;
- k += 3;
- }
- /*------------------------- handle the last (probably partial) block */
- /*
- * "k[2]&0xffffff" actually reads beyond the end of the string, but
- * then masks off the part it's not allowed to read. Because the
- * string is aligned, the masked-off tail is in the same word as the
- * rest of the string. Every machine with memory protection I've seen
- * does it on word boundaries, so is OK with this. But VALGRIND will
- * still catch it and complain. The masking trick does make the hash
- * noticably faster for short strings (like English words).
- */
-#ifndef VALGRIND
-
- switch (size) {
- case 12: c += k[2]; b+=k[1]; a+=k[0]; break;
- case 11: c += k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
- case 10: c += k[2]&0xffff; b+=k[1]; a+=k[0]; break;
- case 9: c += k[2]&0xff; b+=k[1]; a+=k[0]; break;
- case 8: b += k[1]; a+=k[0]; break;
- case 7: b += k[1]&0xffffff; a+=k[0]; break;
- case 6: b += k[1]&0xffff; a+=k[0]; break;
- case 5: b += k[1]&0xff; a+=k[0]; break;
- case 4: a += k[0]; break;
- case 3: a += k[0]&0xffffff; break;
- case 2: a += k[0]&0xffff; break;
- case 1: a += k[0]&0xff; break;
- case 0: goto exit;
- }
-
-#else /* make valgrind happy */
-
- k8 = (const uint8_t *)k;
- switch (size) {
- case 12: c += k[2]; b+=k[1]; a+=k[0]; break;
- case 11: c += ((uint32_t)k8[10])<<16; /*@fallthrough@*/
- case 10: c += ((uint32_t)k8[9])<<8; /*@fallthrough@*/
- case 9: c += k8[8]; /*@fallthrough@*/
- case 8: b += k[1]; a+=k[0]; break;
- case 7: b += ((uint32_t)k8[6])<<16; /*@fallthrough@*/
- case 6: b += ((uint32_t)k8[5])<<8; /*@fallthrough@*/
- case 5: b += k8[4]; /*@fallthrough@*/
- case 4: a += k[0]; break;
- case 3: a += ((uint32_t)k8[2])<<16; /*@fallthrough@*/
- case 2: a += ((uint32_t)k8[1])<<8; /*@fallthrough@*/
- case 1: a += k8[0]; break;
- case 0: goto exit;
- }
-
-#endif /* !valgrind */
-
- } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
- const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
- const uint8_t *k8;
-
- /*----------- all but last block: aligned reads and different mixing */
- while (size > (size_t)12) {
- a += k[0] + (((uint32_t)k[1])<<16);
- b += k[2] + (((uint32_t)k[3])<<16);
- c += k[4] + (((uint32_t)k[5])<<16);
- _JLU3_MIX(a,b,c);
- size -= 12;
- k += 6;
- }
-
- /*------------------------- handle the last (probably partial) block */
- k8 = (const uint8_t *)k;
- switch (size) {
- case 12:
- c += k[4]+(((uint32_t)k[5])<<16);
- b += k[2]+(((uint32_t)k[3])<<16);
- a += k[0]+(((uint32_t)k[1])<<16);
- break;
- case 11:
- c += ((uint32_t)k8[10])<<16;
- /*@fallthrough@*/
- case 10:
- c += k[4];
- b += k[2]+(((uint32_t)k[3])<<16);
- a += k[0]+(((uint32_t)k[1])<<16);
- break;
- case 9:
- c += k8[8];
- /*@fallthrough@*/
- case 8:
- b += k[2]+(((uint32_t)k[3])<<16);
- a += k[0]+(((uint32_t)k[1])<<16);
- break;
- case 7:
- b += ((uint32_t)k8[6])<<16;
- /*@fallthrough@*/
- case 6:
- b += k[2];
- a += k[0]+(((uint32_t)k[1])<<16);
- break;
- case 5:
- b += k8[4];
- /*@fallthrough@*/
- case 4:
- a += k[0]+(((uint32_t)k[1])<<16);
- break;
- case 3:
- a += ((uint32_t)k8[2])<<16;
- /*@fallthrough@*/
- case 2:
- a += k[0];
- break;
- case 1:
- a += k8[0];
- break;
- case 0:
- goto exit;
- }
-
- } else { /* need to read the key one byte at a time */
- const uint8_t *k = (const uint8_t *)key;
-
- /*----------- all but the last block: affect some 32 bits of (a,b,c) */
- while (size > (size_t)12) {
- a += k[0];
- a += ((uint32_t)k[1])<<8;
- a += ((uint32_t)k[2])<<16;
- a += ((uint32_t)k[3])<<24;
- b += k[4];
- b += ((uint32_t)k[5])<<8;
- b += ((uint32_t)k[6])<<16;
- b += ((uint32_t)k[7])<<24;
- c += k[8];
- c += ((uint32_t)k[9])<<8;
- c += ((uint32_t)k[10])<<16;
- c += ((uint32_t)k[11])<<24;
- _JLU3_MIX(a,b,c);
- size -= 12;
- k += 12;
- }
-
- /*---------------------------- last block: affect all 32 bits of (c) */
- switch (size) {
- case 12: c += ((uint32_t)k[11])<<24; /*@fallthrough@*/
- case 11: c += ((uint32_t)k[10])<<16; /*@fallthrough@*/
- case 10: c += ((uint32_t)k[9])<<8; /*@fallthrough@*/
- case 9: c += k[8]; /*@fallthrough@*/
- case 8: b += ((uint32_t)k[7])<<24; /*@fallthrough@*/
- case 7: b += ((uint32_t)k[6])<<16; /*@fallthrough@*/
- case 6: b += ((uint32_t)k[5])<<8; /*@fallthrough@*/
- case 5: b += k[4]; /*@fallthrough@*/
- case 4: a += ((uint32_t)k[3])<<24; /*@fallthrough@*/
- case 3: a += ((uint32_t)k[2])<<16; /*@fallthrough@*/
- case 2: a += ((uint32_t)k[1])<<8; /*@fallthrough@*/
- case 1: a += k[0];
- break;
- case 0:
- goto exit;
- }
- }
-
- _JLU3_FINAL(a,b,c);
-
-exit:
- *pc = c;
- *pb = b;
- return;
-}
-#endif /* defined(_JLU3_jlu32lpair) */
-
-#if defined(_JLU3_jlu32b)
-uint32_t jlu32b(uint32_t h, /*@null@*/ const void *key, size_t size)
- /*@*/;
-/*
- * jlu32b():
- * This is the same as jlu32w() on big-endian machines. It is different
- * from jlu32l() on all machines. jlu32b() takes advantage of
- * big-endian byte ordering.
- *
- * @param h the previous hash, or an arbitrary value
- * @param *k the key, an array of uint8_t values
- * @param size the size of the key
- * @return the lookup3 hash
- */
-uint32_t jlu32b(uint32_t h, const void *key, size_t size)
-{
- union { const void *ptr; size_t i; } u;
- uint32_t a = _JLU3_INIT(h, size);
- uint32_t b = a;
- uint32_t c = a;
-
- if (key == NULL)
- return h;
-
- u.ptr = key;
- if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) {
- const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
-#ifdef VALGRIND
- const uint8_t *k8;
-#endif
-
- /*-- all but last block: aligned reads and affect 32 bits of (a,b,c) */
- while (size > 12) {
- a += k[0];
- b += k[1];
- c += k[2];
- _JLU3_MIX(a,b,c);
- size -= 12;
- k += 3;
- }
-
- /*------------------------- handle the last (probably partial) block */
- /*
- * "k[2]<<8" actually reads beyond the end of the string, but
- * then shifts out the part it's not allowed to read. Because the
- * string is aligned, the illegal read is in the same word as the
- * rest of the string. Every machine with memory protection I've seen
- * does it on word boundaries, so is OK with this. But VALGRIND will
- * still catch it and complain. The masking trick does make the hash
- * noticably faster for short strings (like English words).
- */
-#ifndef VALGRIND
-
- switch (size) {
- case 12: c += k[2]; b+=k[1]; a+=k[0]; break;
- case 11: c += k[2]&0xffffff00; b+=k[1]; a+=k[0]; break;
- case 10: c += k[2]&0xffff0000; b+=k[1]; a+=k[0]; break;
- case 9: c += k[2]&0xff000000; b+=k[1]; a+=k[0]; break;
- case 8: b += k[1]; a+=k[0]; break;
- case 7: b += k[1]&0xffffff00; a+=k[0]; break;
- case 6: b += k[1]&0xffff0000; a+=k[0]; break;
- case 5: b += k[1]&0xff000000; a+=k[0]; break;
- case 4: a += k[0]; break;
- case 3: a += k[0]&0xffffff00; break;
- case 2: a += k[0]&0xffff0000; break;
- case 1: a += k[0]&0xff000000; break;
- case 0: goto exit;
- }
-
-#else /* make valgrind happy */
-
- k8 = (const uint8_t *)k;
- switch (size) { /* all the case statements fall through */
- case 12: c += k[2]; b+=k[1]; a+=k[0]; break;
- case 11: c += ((uint32_t)k8[10])<<8; /*@fallthrough@*/
- case 10: c += ((uint32_t)k8[9])<<16; /*@fallthrough@*/
- case 9: c += ((uint32_t)k8[8])<<24; /*@fallthrough@*/
- case 8: b += k[1]; a+=k[0]; break;
- case 7: b += ((uint32_t)k8[6])<<8; /*@fallthrough@*/
- case 6: b += ((uint32_t)k8[5])<<16; /*@fallthrough@*/
- case 5: b += ((uint32_t)k8[4])<<24; /*@fallthrough@*/
- case 4: a += k[0]; break;
- case 3: a += ((uint32_t)k8[2])<<8; /*@fallthrough@*/
- case 2: a += ((uint32_t)k8[1])<<16; /*@fallthrough@*/
- case 1: a += ((uint32_t)k8[0])<<24; break;
- case 0: goto exit;
- }
-
-#endif /* !VALGRIND */
-
- } else { /* need to read the key one byte at a time */
- const uint8_t *k = (const uint8_t *)key;
-
- /*----------- all but the last block: affect some 32 bits of (a,b,c) */
- while (size > 12) {
- a += ((uint32_t)k[0])<<24;
- a += ((uint32_t)k[1])<<16;
- a += ((uint32_t)k[2])<<8;
- a += ((uint32_t)k[3]);
- b += ((uint32_t)k[4])<<24;
- b += ((uint32_t)k[5])<<16;
- b += ((uint32_t)k[6])<<8;
- b += ((uint32_t)k[7]);
- c += ((uint32_t)k[8])<<24;
- c += ((uint32_t)k[9])<<16;
- c += ((uint32_t)k[10])<<8;
- c += ((uint32_t)k[11]);
- _JLU3_MIX(a,b,c);
- size -= 12;
- k += 12;
- }
-
- /*---------------------------- last block: affect all 32 bits of (c) */
- switch (size) { /* all the case statements fall through */
- case 12: c += k[11]; /*@fallthrough@*/
- case 11: c += ((uint32_t)k[10])<<8; /*@fallthrough@*/
- case 10: c += ((uint32_t)k[9])<<16; /*@fallthrough@*/
- case 9: c += ((uint32_t)k[8])<<24; /*@fallthrough@*/
- case 8: b += k[7]; /*@fallthrough@*/
- case 7: b += ((uint32_t)k[6])<<8; /*@fallthrough@*/
- case 6: b += ((uint32_t)k[5])<<16; /*@fallthrough@*/
- case 5: b += ((uint32_t)k[4])<<24; /*@fallthrough@*/
- case 4: a += k[3]; /*@fallthrough@*/
- case 3: a += ((uint32_t)k[2])<<8; /*@fallthrough@*/
- case 2: a += ((uint32_t)k[1])<<16; /*@fallthrough@*/
- case 1: a += ((uint32_t)k[0])<<24; /*@fallthrough@*/
- break;
- case 0:
- goto exit;
- }
- }
-
- _JLU3_FINAL(a,b,c);
-
-exit:
- return c;
-}
-#endif /* defined(_JLU3_jlu32b) */
-
-#if defined(_JLU3_SELFTEST)
-
-/* used for timings */
-static void driver1(void)
- /*@*/
-{
- uint8_t buf[256];
- uint32_t i;
- uint32_t h=0;
- time_t a,z;
-
- time(&a);
- for (i=0; i<256; ++i) buf[i] = 'x';
- for (i=0; i<1; ++i) {
- h = jlu32l(h, &buf[0], sizeof(buf[0]));
- }
- time(&z);
- if (z-a > 0) printf("time %d %.8x\n", (int)(z-a), h);
-}
-
-/* check that every input bit changes every output bit half the time */
-#define HASHSTATE 1
-#define HASHLEN 1
-#define MAXPAIR 60
-#define MAXLEN 70
-static void driver2(void)
- /*@*/
-{
- uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1];
- uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z;
- uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE];
- uint32_t x[HASHSTATE],y[HASHSTATE];
- uint32_t hlen;
-
- printf("No more than %d trials should ever be needed \n",MAXPAIR/2);
- for (hlen=0; hlen < MAXLEN; ++hlen) {
- z=0;
- for (i=0; i<hlen; ++i) { /*-------------- for each input byte, */
- for (j=0; j<8; ++j) { /*--------------- for each input bit, */
- for (m=1; m<8; ++m) { /*--- for serveral possible initvals, */
- for (l=0; l<HASHSTATE; ++l)
- e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((uint32_t)0);
-
- /* check that every output bit is affected by that input bit */
- for (k=0; k<MAXPAIR; k+=2) {
- uint32_t finished=1;
- /* keys have one bit different */
- for (l=0; l<hlen+1; ++l) {a[l] = b[l] = (uint8_t)0;}
- /* have a and b be two keys differing in only one bit */
- a[i] ^= (k<<j);
- a[i] ^= (k>>(8-j));
- c[0] = jlu32l(m, a, hlen);
- b[i] ^= ((k+1)<<j);
- b[i] ^= ((k+1)>>(8-j));
- d[0] = jlu32l(m, b, hlen);
- /* check every bit is 1, 0, set, and not set at least once */
- for (l=0; l<HASHSTATE; ++l) {
- e[l] &= (c[l]^d[l]);
- f[l] &= ~(c[l]^d[l]);
- g[l] &= c[l];
- h[l] &= ~c[l];
- x[l] &= d[l];
- y[l] &= ~d[l];
- if (e[l]|f[l]|g[l]|h[l]|x[l]|y[l]) finished=0;
- }
- if (finished) break;
- }
- if (k>z) z=k;
- if (k == MAXPAIR) {
- printf("Some bit didn't change: ");
- printf("%.8x %.8x %.8x %.8x %.8x %.8x ",
- e[0],f[0],g[0],h[0],x[0],y[0]);
- printf("i %d j %d m %d len %d\n", i, j, m, hlen);
- }
- if (z == MAXPAIR) goto done;
- }
- }
- }
- done:
- if (z < MAXPAIR) {
- printf("Mix success %2d bytes %2d initvals ",i,m);
- printf("required %d trials\n", z/2);
- }
- }
- printf("\n");
-}
-
-/* Check for reading beyond the end of the buffer and alignment problems */
-static void driver3(void)
- /*@*/
-{
- uint8_t buf[MAXLEN+20], *b;
- uint32_t len;
- uint8_t q[] = "This is the time for all good men to come to the aid of their country...";
- uint32_t h;
- uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country...";
- uint32_t i;
- uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country...";
- uint32_t j;
- uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country...";
- uint32_t ref,x,y;
- uint8_t *p;
- uint32_t m = 13;
-
- printf("Endianness. These lines should all be the same (for values filled in):\n");
- printf("%.8x %.8x %.8x\n",
- jlu32w(m, (const uint32_t *)q, (sizeof(q)-1)/4),
- jlu32w(m, (const uint32_t *)q, (sizeof(q)-5)/4),
- jlu32w(m, (const uint32_t *)q, (sizeof(q)-9)/4));
- p = q;
- printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
- jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2),
- jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4),
- jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6),
- jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8),
- jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10),
- jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12));
- p = &qq[1];
- printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
- jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2),
- jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4),
- jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6),
- jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8),
- jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10),
- jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12));
- p = &qqq[2];
- printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
- jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2),
- jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4),
- jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6),
- jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8),
- jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10),
- jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12));
- p = &qqqq[3];
- printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
- jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2),
- jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4),
- jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6),
- jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8),
- jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10),
- jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12));
- printf("\n");
- for (h=0, b=buf+1; h<8; ++h, ++b) {
- for (i=0; i<MAXLEN; ++i) {
- len = i;
- for (j=0; j<i; ++j)
- *(b+j)=0;
-
- /* these should all be equal */
- m = 1;
- ref = jlu32l(m, b, len);
- *(b+i)=(uint8_t)~0;
- *(b-1)=(uint8_t)~0;
- x = jlu32l(m, b, len);
- y = jlu32l(m, b, len);
- if ((ref != x) || (ref != y))
- printf("alignment error: %.8x %.8x %.8x %d %d\n",ref,x,y, h, i);
- }
- }
-}
-
-/* check for problems with nulls */
-static void driver4(void)
- /*@*/
-{
- uint8_t buf[1];
- uint32_t h;
- uint32_t i;
- uint32_t state[HASHSTATE];
-
- buf[0] = ~0;
- for (i=0; i<HASHSTATE; ++i)
- state[i] = 1;
- printf("These should all be different\n");
- h = 0;
- for (i=0; i<8; ++i) {
- h = jlu32l(h, buf, 0);
- printf("%2ld 0-byte strings, hash is %.8x\n", (long)i, h);
- }
-}
-
-
-int main(int argc, char ** argv)
-{
- driver1(); /* test that the key is hashed: used for timings */
- driver2(); /* test that whole key is hashed thoroughly */
- driver3(); /* test that nothing but the key is hashed */
- driver4(); /* test hashing multiple buffers (all buffers are null) */
- return 1;
-}
-
-#endif /* _JLU3_SELFTEST */
diff --git a/third_party/popt/popt.c b/third_party/popt/popt.c
index c6bae95..d9e8411 100644
--- a/third_party/popt/popt.c
+++ b/third_party/popt/popt.c
@@ -10,19 +10,12 @@
#include "system.h"
-#if defined(__LCLINT__)
-/*@-declundef -exportheader @*/
-extern long long int strtoll(const char *nptr, /*@null@*/ char **endptr,
- int base)
- /*@modifies *endptr@*/;
-/*@=declundef =exportheader @*/
-#endif
-
-#ifdef HAVE_FLOAT_H
+#if HAVE_FLOAT_H
#include <float.h>
#endif
#include <math.h>
+#include "findme.h"
#include "poptint.h"
#ifdef MYDEBUG
@@ -30,14 +23,8 @@ extern long long int strtoll(const char *nptr, /*@null@*/ char **endptr,
int _popt_debug = 0;
#endif
-/*@unchecked@*/
-unsigned int _poptArgMask = POPT_ARG_MASK;
-/*@unchecked@*/
-unsigned int _poptGroupMask = POPT_GROUP_MASK;
-
-#if !defined(HAVE_STRERROR) && !defined(__LCLINT__)
-static char * strerror(int errno)
-{
+#ifndef HAVE_STRERROR
+static char * strerror(int errno) {
extern int sys_nerr;
extern char * sys_errlist[];
@@ -49,8 +36,7 @@ static char * strerror(int errno)
#endif
#ifdef MYDEBUG
-/*@unused@*/
-static void prtcon(const char *msg, poptContext con)
+/*@unused@*/ static void prtcon(const char *msg, poptContext con)
{
if (msg) fprintf(stderr, "%s", msg);
fprintf(stderr, "\tcon %p os %p nextCharArg \"%s\" nextArg \"%s\" argv[%d] \"%s\"\n",
@@ -65,10 +51,12 @@ static void prtcon(const char *msg, poptContext con)
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute)
{
- con->execPath = _free(con->execPath);
+ con->execPath = (const char *)_free(con->execPath);
con->execPath = xstrdup(path);
con->execAbsolute = allowAbsolute;
+ /*@-nullstate@*/ /* LCL: con->execPath can be NULL? */
return;
+ /*@=nullstate@*/
}
static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt)
@@ -77,20 +65,19 @@ static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt)
{
if (opt != NULL)
for (; opt->longName || opt->shortName || opt->arg; opt++) {
- poptArg arg = { .ptr = opt->arg };
- if (arg.ptr)
- switch (poptArgType(opt)) {
- case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
- poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
- invokeCallbacksPRE(con, arg.opt);
- /*@switchbreak@*/ break;
- case POPT_ARG_CALLBACK: /* Perform callback. */
- if (!CBF_ISSET(opt, PRE))
- /*@switchbreak@*/ break;
-/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */
- arg.cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip);
-/*@=noeffectuncon @*/
- /*@switchbreak@*/ break;
+ if (opt->arg == NULL) continue; /* XXX program error. */
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
+ /* Recurse on included sub-tables. */
+ invokeCallbacksPRE(con, (const struct poptOption *)opt->arg);
+ } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK &&
+ (opt->argInfo & POPT_CBFLAG_PRE))
+ { /*@-castfcnptr@*/
+ poptCallbackType cb = (poptCallbackType)opt->arg;
+ /*@=castfcnptr@*/
+ /* Perform callback. */
+ /*@-moduncon -noeffectuncon @*/
+ cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip);
+ /*@=moduncon =noeffectuncon @*/
}
}
}
@@ -101,109 +88,114 @@ static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt)
{
if (opt != NULL)
for (; opt->longName || opt->shortName || opt->arg; opt++) {
- poptArg arg = { .ptr = opt->arg };
- if (arg.ptr)
- switch (poptArgType(opt)) {
- case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
- poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
- invokeCallbacksPOST(con, arg.opt);
- /*@switchbreak@*/ break;
- case POPT_ARG_CALLBACK: /* Perform callback. */
- if (!CBF_ISSET(opt, POST))
- /*@switchbreak@*/ break;
-/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */
- arg.cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip);
-/*@=noeffectuncon @*/
- /*@switchbreak@*/ break;
+ if (opt->arg == NULL) continue; /* XXX program error. */
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
+ /* Recurse on included sub-tables. */
+ invokeCallbacksPOST(con, (const struct poptOption *)opt->arg);
+ } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK &&
+ (opt->argInfo & POPT_CBFLAG_POST))
+ { /*@-castfcnptr@*/
+ poptCallbackType cb = (poptCallbackType)opt->arg;
+ /*@=castfcnptr@*/
+ /* Perform callback. */
+ /*@-moduncon -noeffectuncon @*/
+ cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip);
+ /*@=moduncon =noeffectuncon @*/
}
}
}
static void invokeCallbacksOPTION(poptContext con,
- const struct poptOption * opt,
- const struct poptOption * myOpt,
- /*@null@*/ const void * myData, int shorty)
+ const struct poptOption * opt,
+ const struct poptOption * myOpt,
+ /*@null@*/ const void * myData, int shorty)
/*@globals internalState@*/
/*@modifies internalState@*/
{
const struct poptOption * cbopt = NULL;
- poptArg cbarg = { .ptr = NULL };
if (opt != NULL)
for (; opt->longName || opt->shortName || opt->arg; opt++) {
- poptArg arg = { .ptr = opt->arg };
- switch (poptArgType(opt)) {
- case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
- poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
- if (opt->arg != NULL)
- invokeCallbacksOPTION(con, opt->arg, myOpt, myData, shorty);
- /*@switchbreak@*/ break;
- case POPT_ARG_CALLBACK: /* Save callback info. */
- if (CBF_ISSET(opt, SKIPOPTION))
- /*@switchbreak@*/ break;
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
+ /* Recurse on included sub-tables. */
+ if (opt->arg != NULL) /* XXX program error */
+ invokeCallbacksOPTION(con, (const struct poptOption *)opt->arg,
+ myOpt, myData, shorty);
+ } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK &&
+ !(opt->argInfo & POPT_CBFLAG_SKIPOPTION)) {
+ /* Save callback info. */
cbopt = opt;
- cbarg.ptr = opt->arg;
- /*@switchbreak@*/ break;
- default: /* Perform callback on matching option. */
- if (cbopt == NULL || cbarg.cb == NULL)
- /*@switchbreak@*/ break;
- if ((myOpt->shortName && opt->shortName && shorty &&
- myOpt->shortName == opt->shortName)
- || (myOpt->longName != NULL && opt->longName != NULL &&
+ } else if (cbopt != NULL &&
+ ((myOpt->shortName && opt->shortName && shorty &&
+ myOpt->shortName == opt->shortName) ||
+ (myOpt->longName && opt->longName &&
+ /*@-nullpass@*/ /* LCL: opt->longName != NULL */
!strcmp(myOpt->longName, opt->longName)))
- { const void *cbData = (cbopt->descrip ? cbopt->descrip : myData);
-/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */
- cbarg.cb(con, POPT_CALLBACK_REASON_OPTION,
- myOpt, con->os->nextArg, cbData);
-/*@=noeffectuncon @*/
- /* Terminate (unless explcitly continuing). */
- if (!CBF_ISSET(cbopt, CONTINUE))
- return;
+ /*@=nullpass@*/
+ )
+ { /*@-castfcnptr@*/
+ poptCallbackType cb = (poptCallbackType)cbopt->arg;
+ /*@=castfcnptr@*/
+ const void * cbData = (cbopt->descrip ? cbopt->descrip : myData);
+ /* Perform callback. */
+ if (cb != NULL) { /* XXX program error */
+ /*@-moduncon -noeffectuncon @*/
+ cb(con, POPT_CALLBACK_REASON_OPTION, myOpt,
+ con->os->nextArg, cbData);
+ /*@=moduncon =noeffectuncon @*/
}
- /*@switchbreak@*/ break;
+ /* Terminate (unless explcitly continuing). */
+ if (!(cbopt->argInfo & POPT_CBFLAG_CONTINUE))
+ return;
}
}
}
poptContext poptGetContext(const char * name, int argc, const char ** argv,
- const struct poptOption * options, unsigned int flags)
+ const struct poptOption * options, int flags)
{
- poptContext con = malloc(sizeof(*con));
+ poptContext con = (poptContext)malloc(sizeof(*con));
if (con == NULL) return NULL; /* XXX can't happen */
memset(con, 0, sizeof(*con));
con->os = con->optionStack;
con->os->argc = argc;
-/*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */
+ /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */
con->os->argv = argv;
-/*@=dependenttrans =assignexpose@*/
+ /*@=dependenttrans =assignexpose@*/
con->os->argb = NULL;
if (!(flags & POPT_CONTEXT_KEEP_FIRST))
- con->os->next = 1; /* skip argv[0] */
+ con->os->next = 1; /* skip argv[0] */
- con->leftovers = calloc( (size_t)(argc + 1), sizeof(*con->leftovers) );
-/*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */
+ con->leftovers = (const char **)calloc( (argc + 1),
+ sizeof(*con->leftovers) );
+ /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */
con->options = options;
-/*@=dependenttrans =assignexpose@*/
+ /*@=dependenttrans =assignexpose@*/
con->aliases = NULL;
con->numAliases = 0;
con->flags = flags;
con->execs = NULL;
con->numExecs = 0;
con->finalArgvAlloced = argc * 2;
- con->finalArgv = calloc( (size_t)con->finalArgvAlloced, sizeof(*con->finalArgv) );
+ con->finalArgv = (const char **)calloc( con->finalArgvAlloced,
+ sizeof(*con->finalArgv) );
con->execAbsolute = 1;
con->arg_strip = NULL;
if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER"))
con->flags |= POPT_CONTEXT_POSIXMEHARDER;
- if (name)
- con->appName = xstrdup(name);
+ if (name) {
+ char * t = (char *)malloc(strlen(name) + 1);
+ if (t) con->appName = strcpy(t, name);
+ }
+ /*@-internalglobs@*/
invokeCallbacksPRE(con, con->options);
+ /*@=internalglobs@*/
return con;
}
@@ -213,11 +205,12 @@ static void cleanOSE(/*@special@*/ struct optionStackEntry *os)
/*@releases os->nextArg, os->argv, os->argb @*/
/*@modifies os @*/
{
- os->nextArg = _free(os->nextArg);
- os->argv = _free(os->argv);
- os->argb = PBM_FREE(os->argb);
+ os->nextArg = (const char *)_free(os->nextArg);
+ os->argv = (const char **)_free(os->argv);
+ os->argb = (pbm_set *)PBM_FREE(os->argb);
}
+/*@-boundswrite@*/
void poptResetContext(poptContext con)
{
int i;
@@ -226,7 +219,7 @@ void poptResetContext(poptContext con)
while (con->os > con->optionStack) {
cleanOSE(con->os--);
}
- con->os->argb = PBM_FREE(con->os->argb);
+ con->os->argb = (pbm_set *)PBM_FREE(con->os->argb);
con->os->currAlias = NULL;
con->os->nextCharArg = NULL;
con->os->nextArg = NULL;
@@ -239,19 +232,21 @@ void poptResetContext(poptContext con)
if (con->finalArgv != NULL)
for (i = 0; i < con->finalArgvCount; i++) {
-/*@-unqualifiedtrans@*/ /* FIX: typedef double indirection. */
- con->finalArgv[i] = _free(con->finalArgv[i]);
-/*@=unqualifiedtrans@*/
+ /*@-unqualifiedtrans@*/ /* FIX: typedef double indirection. */
+ con->finalArgv[i] = (const char *)_free(con->finalArgv[i]);
+ /*@=unqualifiedtrans@*/
}
con->finalArgvCount = 0;
- con->arg_strip = PBM_FREE(con->arg_strip);
-/*@-nullstate@*/ /* FIX: con->finalArgv != NULL */
+ con->arg_strip = ( pbm_set *)PBM_FREE(con->arg_strip);
+ /*@-nullstate@*/ /* FIX: con->finalArgv != NULL */
return;
-/*@=nullstate@*/
+ /*@=nullstate@*/
}
+/*@=boundswrite@*/
/* Only one of longName, shortName should be set, not both. */
+/*@-boundswrite@*/
static int handleExec(/*@special@*/ poptContext con,
/*@null@*/ const char * longName, char shortName)
/*@uses con->execs, con->numExecs, con->flags, con->doExec,
@@ -288,72 +283,33 @@ static int handleExec(/*@special@*/ poptContext con,
time 'round */
if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) {
con->finalArgvAlloced += 10;
- con->finalArgv = realloc(con->finalArgv,
+ con->finalArgv = (const char **)realloc(con->finalArgv,
sizeof(*con->finalArgv) * con->finalArgvAlloced);
}
i = con->finalArgvCount++;
if (con->finalArgv != NULL) /* XXX can't happen */
- { char *s = malloc((longName ? strlen(longName) : 0) + sizeof("--"));
+ { char *s = (char *)malloc((longName ? strlen(longName) : 0) + 3);
if (s != NULL) { /* XXX can't happen */
- con->finalArgv[i] = s;
- *s++ = '-';
if (longName)
- s = stpcpy( stpcpy(s, "-"), longName);
+ sprintf(s, "--%s", longName);
else
- *s++ = shortName;
- *s = '\0';
+ sprintf(s, "-%c", shortName);
+ con->finalArgv[i] = s;
} else
con->finalArgv[i] = NULL;
}
+ /*@-nullstate@*/ /* FIX: con->finalArgv[] == NULL */
return 1;
+ /*@=nullstate@*/
}
-
-/**
- * Compare long option for equality, adjusting for POPT_ARGFLAG_TOGGLE.
- * @param opt option
- * @param longName arg option
- * @param longNameLen arg option length
- * @return does long option match?
- */
-static int
-longOptionStrcmp(const struct poptOption * opt,
- /*@null@*/ const char * longName, size_t longNameLen)
- /*@*/
-{
- const char * optLongName = opt->longName;
- int rc;
-
- if (optLongName == NULL || longName == NULL) /* XXX can't heppen */
- return 0;
-
- if (F_ISSET(opt, TOGGLE)) {
- if (optLongName[0] == 'n' && optLongName[1] == 'o') {
- optLongName += sizeof("no") - 1;
- if (optLongName[0] == '-')
- optLongName++;
- }
- if (longName[0] == 'n' && longName[1] == 'o') {
- longName += sizeof("no") - 1;
- longNameLen -= sizeof("no") - 1;
- if (longName[0] == '-') {
- longName++;
- longNameLen--;
- }
- }
- }
- rc = (int)(strlen(optLongName) == longNameLen);
- if (rc)
- rc = (int)(strncmp(optLongName, longName, longNameLen) == 0);
- return rc;
-}
+/*@=boundswrite@*/
/* Only one of longName, shortName may be set at a time */
static int handleAlias(/*@special@*/ poptContext con,
- /*@null@*/ const char * longName, size_t longNameLen,
- char shortName,
- /*@exposed@*/ /*@null@*/ const char * nextArg)
+ /*@null@*/ const char * longName, char shortName,
+ /*@exposed@*/ /*@null@*/ const char * nextCharArg)
/*@uses con->aliases, con->numAliases, con->optionStack, con->os,
con->os->currAlias, con->os->currAlias->option.longName @*/
/*@modifies con @*/
@@ -363,10 +319,9 @@ static int handleAlias(/*@special@*/ poptContext con,
int i;
if (item) {
- if (longName && item->option.longName != NULL
- && longOptionStrcmp(&item->option, longName, longNameLen))
+ if (longName && (item->option.longName &&
+ !strcmp(longName, item->option.longName)))
return 0;
- else
if (shortName && shortName == item->option.shortName)
return 0;
}
@@ -376,12 +331,10 @@ static int handleAlias(/*@special@*/ poptContext con,
for (i = con->numAliases - 1; i >= 0; i--) {
item = con->aliases + i;
- if (longName) {
- if (item->option.longName == NULL)
- continue;
- if (!longOptionStrcmp(&item->option, longName, longNameLen))
- continue;
- } else if (shortName != item->option.shortName)
+ if (longName && !(item->option.longName &&
+ !strcmp(longName, item->option.longName)))
+ continue;
+ else if (shortName != item->option.shortName)
continue;
break;
}
@@ -390,8 +343,10 @@ static int handleAlias(/*@special@*/ poptContext con,
if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH)
return POPT_ERROR_OPTSTOODEEP;
- if (longName == NULL && nextArg != NULL && *nextArg != '\0')
- con->os->nextCharArg = nextArg;
+/*@-boundsread@*/
+ if (nextCharArg && *nextCharArg)
+ con->os->nextCharArg = nextCharArg;
+/*@=boundsread@*/
con->os++;
con->os->next = 0;
@@ -399,89 +354,22 @@ static int handleAlias(/*@special@*/ poptContext con,
con->os->nextArg = NULL;
con->os->nextCharArg = NULL;
con->os->currAlias = con->aliases + i;
- { const char ** av;
- int ac = con->os->currAlias->argc;
- /* Append --foo=bar arg to alias argv array (if present). */
- if (longName && nextArg != NULL && *nextArg != '\0') {
- av = malloc((ac + 1 + 1) * sizeof(*av));
- if (av != NULL) { /* XXX won't happen. */
- for (i = 0; i < ac; i++) {
- av[i] = con->os->currAlias->argv[i];
- }
- av[ac++] = nextArg;
- av[ac] = NULL;
- } else /* XXX revert to old popt behavior if malloc fails. */
- av = con->os->currAlias->argv;
- } else
- av = con->os->currAlias->argv;
- rc = poptDupArgv(ac, av, &con->os->argc, &con->os->argv);
- if (av != NULL && av != con->os->currAlias->argv)
- free(av);
- }
+ rc = poptDupArgv(con->os->currAlias->argc, con->os->currAlias->argv,
+ &con->os->argc, &con->os->argv);
con->os->argb = NULL;
return (rc ? rc : 1);
}
-/**
- * Return absolute path to executable by searching PATH.
- * @param argv0 name of executable
- * @return (malloc'd) absolute path to executable (or NULL)
- */
-static /*@null@*/
-const char * findProgramPath(/*@null@*/ const char * argv0)
- /*@*/
-{
- char *path = NULL, *s = NULL, *se;
- char *t = NULL;
-
- if (argv0 == NULL) return NULL; /* XXX can't happen */
-
- /* If there is a / in argv[0], it has to be an absolute path. */
- /* XXX Hmmm, why not if (argv0[0] == '/') ... instead? */
- if (strchr(argv0, '/'))
- return xstrdup(argv0);
-
- if ((path = getenv("PATH")) == NULL || (path = xstrdup(path)) == NULL)
- return NULL;
-
- /* The return buffer in t is big enough for any path. */
- if ((t = malloc(strlen(path) + strlen(argv0) + sizeof("/"))) != NULL)
- for (s = path; s && *s; s = se) {
-
- /* Snip PATH element into [s,se). */
- if ((se = strchr(s, ':')))
- *se++ = '\0';
-
- /* Append argv0 to PATH element. */
- (void) stpcpy(stpcpy(stpcpy(t, s), "/"), argv0);
-
- /* If file is executable, bingo! */
- if (!access(t, X_OK))
- break;
- }
-
- /* If no executable was found in PATH, return NULL. */
-/*@-compdef@*/
- if (!(s && *s) && t != NULL)
- t = _free(t);
-/*@=compdef@*/
-/*@-modobserver -observertrans -usedef @*/
- path = _free(path);
-/*@=modobserver =observertrans =usedef @*/
-
- return t;
-}
-
+/*@-bounds -boundswrite @*/
static int execCommand(poptContext con)
/*@globals internalState @*/
/*@modifies internalState @*/
{
poptItem item = con->doExec;
- poptArgv argv = NULL;
+ const char ** argv;
int argc = 0;
int rc;
- int ec = POPT_ERROR_ERRNO;
if (item == NULL) /*XXX can't happen*/
return POPT_ERROR_NOARG;
@@ -490,22 +378,19 @@ static int execCommand(poptContext con)
(!con->execAbsolute && strchr(item->argv[0], '/')))
return POPT_ERROR_NOARG;
- argv = malloc(sizeof(*argv) *
- (6 + item->argc + con->numLeftovers + con->finalArgvCount));
- if (argv == NULL) return POPT_ERROR_MALLOC;
-
- if (!strchr(item->argv[0], '/') && con->execPath != NULL) {
- char *s = malloc(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/"));
- if (s)
- (void)stpcpy(stpcpy(stpcpy(s, con->execPath), "/"), item->argv[0]);
+ argv = (const char **)malloc(
+ sizeof(*argv) * (6 + item->argc + con->numLeftovers + con->finalArgvCount));
+ if (argv == NULL) return POPT_ERROR_MALLOC; /* XXX can't happen */
+ if (!strchr(item->argv[0], '/') && con->execPath) {
+ char *s = (char *)alloca(
+ strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/"));
+ sprintf(s, "%s/%s", con->execPath, item->argv[0]);
argv[argc] = s;
- } else
+ } else {
argv[argc] = findProgramPath(item->argv[0]);
- if (argv[argc++] == NULL) {
- ec = POPT_ERROR_NOARG;
- goto exit;
}
+ if (argv[argc++] == NULL) return POPT_ERROR_NOARG;
if (item->argc > 1) {
memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1));
@@ -519,17 +404,18 @@ static int execCommand(poptContext con)
}
if (con->leftovers != NULL && con->numLeftovers > 0) {
+#if 0
+ argv[argc++] = "--";
+#endif
memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers);
argc += con->numLeftovers;
}
argv[argc] = NULL;
-#if defined(hpux) || defined(__hpux)
- rc = setresgid(getgid(), getgid(),-1);
- if (rc) goto exit;
+#ifdef __hpux
rc = setresuid(getuid(), getuid(),-1);
- if (rc) goto exit;
+ if (rc) return POPT_ERROR_ERRNO;
#else
/*
* XXX " ... on BSD systems setuid() should be preferred over setreuid()"
@@ -537,23 +423,22 @@ static int execCommand(poptContext con)
* XXX from Norbert Warmuth <nwarmuth@privat.circular.de>
*/
#if defined(HAVE_SETUID)
- rc = setgid(getgid());
- if (rc) goto exit;
rc = setuid(getuid());
- if (rc) goto exit;
+ if (rc) return POPT_ERROR_ERRNO;
#elif defined (HAVE_SETREUID)
- rc = setregid(getgid(), getgid());
- if (rc) goto exit;
- rc = setreuid(getuid(), getuid());
- if (rc) goto exit;
+ rc = setreuid(getuid(), getuid()); /*hlauer: not portable to hpux9.01 */
+ if (rc) return POPT_ERROR_ERRNO;
#else
; /* Can't drop privileges */
#endif
#endif
+ if (argv[0] == NULL)
+ return POPT_ERROR_NOARG;
+
#ifdef MYDEBUG
if (_popt_debug)
- { poptArgv avp;
+ { const char ** avp;
fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc);
for (avp = argv; *avp; avp++)
fprintf(stderr, " '%s'", *avp);
@@ -561,68 +446,56 @@ if (_popt_debug)
}
#endif
-/*@-nullstate@*/
rc = execvp(argv[0], (char *const *)argv);
-/*@=nullstate@*/
-
-exit:
- if (argv) {
- if (argv[0])
- free((void *)argv[0]);
- free(argv);
+ /* notreached */
+ if (rc) {
+ return POPT_ERROR_ERRNO;
}
- return ec;
+
+ return 0;
}
+/*@=bounds =boundswrite @*/
-/*@observer@*/ /*@null@*/
-static const struct poptOption *
-findOption(const struct poptOption * opt,
- /*@null@*/ const char * longName, size_t longNameLen,
+/*@-boundswrite@*/
+/*@observer@*/ /*@null@*/ static const struct poptOption *
+findOption(const struct poptOption * opt, /*@null@*/ const char * longName,
char shortName,
/*@null@*/ /*@out@*/ poptCallbackType * callback,
/*@null@*/ /*@out@*/ const void ** callbackData,
- unsigned int argInfo)
+ int singleDash)
/*@modifies *callback, *callbackData */
{
const struct poptOption * cb = NULL;
- poptArg cbarg = { .ptr = NULL };
/* This happens when a single - is given */
- if (LF_ISSET(ONEDASH) && !shortName && (longName && *longName == '\0'))
+ if (singleDash && !shortName && (longName && *longName == '\0'))
shortName = '-';
for (; opt->longName || opt->shortName || opt->arg; opt++) {
- poptArg arg = { .ptr = opt->arg };
- switch (poptArgType(opt)) {
- case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
- { const struct poptOption * opt2;
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
+ const struct poptOption * opt2;
- poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
- if (arg.ptr == NULL) continue; /* XXX program error */
- opt2 = findOption(arg.opt, longName, longNameLen, shortName, callback,
- callbackData, argInfo);
+ /* Recurse on included sub-tables. */
+ if (opt->arg == NULL) continue; /* XXX program error */
+ opt2 = findOption((const struct poptOption *)opt->arg, longName,
+ shortName, callback,
+ callbackData, singleDash);
if (opt2 == NULL) continue;
/* Sub-table data will be inheirited if no data yet. */
-/*@-observertrans -dependenttrans @*/
- if (callback && *callback
- && callbackData && *callbackData == NULL)
- *callbackData = opt->descrip;
-/*@=observertrans =dependenttrans @*/
+ if (!(callback && *callback)) return opt2;
+ if (!(callbackData && *callbackData == NULL)) return opt2;
+ /*@-observertrans -dependenttrans @*/
+ *callbackData = opt->descrip;
+ /*@=observertrans =dependenttrans @*/
return opt2;
- } /*@notreached@*/ /*@switchbreak@*/ break;
- case POPT_ARG_CALLBACK:
+ } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) {
cb = opt;
- cbarg.ptr = opt->arg;
- continue;
- /*@notreached@*/ /*@switchbreak@*/ break;
- default:
- /*@switchbreak@*/ break;
- }
-
- if (longName != NULL && opt->longName != NULL &&
- (!LF_ISSET(ONEDASH) || F_ISSET(opt, ONEDASH)) &&
- longOptionStrcmp(opt, longName, longNameLen))
+ } else if (longName && opt->longName &&
+ (!singleDash || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) &&
+ /*@-nullpass@*/ /* LCL: opt->longName != NULL */
+ !strcmp(longName, opt->longName))
+ /*@=nullpass@*/
{
break;
} else if (shortName && shortName == opt->shortName) {
@@ -630,20 +503,28 @@ findOption(const struct poptOption * opt,
}
}
- if (opt->longName == NULL && !opt->shortName)
+ if (!opt->longName && !opt->shortName)
return NULL;
-
-/*@-modobserver -mods @*/
- if (callback)
- *callback = (cb ? cbarg.cb : NULL);
- if (callbackData)
-/*@-observertrans -dependenttrans @*/
- *callbackData = (cb && !CBF_ISSET(cb, INC_DATA) ? cb->descrip : NULL);
-/*@=observertrans =dependenttrans @*/
-/*@=modobserver =mods @*/
+ /*@-modobserver -mods @*/
+ if (callback) *callback = NULL;
+ if (callbackData) *callbackData = NULL;
+ if (cb) {
+ if (callback)
+ /*@-castfcnptr@*/
+ *callback = (poptCallbackType)cb->arg;
+ /*@=castfcnptr@*/
+ if (!(cb->argInfo & POPT_CBFLAG_INC_DATA)) {
+ if (callbackData)
+ /*@-observertrans@*/ /* FIX: typedef double indirection. */
+ *callbackData = cb->descrip;
+ /*@=observertrans@*/
+ }
+ }
+ /*@=modobserver =mods @*/
return opt;
}
+/*@=boundswrite@*/
static const char * findNextArg(/*@special@*/ poptContext con,
unsigned argx, int delete_arg)
@@ -661,7 +542,7 @@ static const char * findNextArg(/*@special@*/ poptContext con,
if (os->next == os->argc && os == con->optionStack) break;
if (os->argv != NULL)
for (i = os->next; i < os->argc; i++) {
-/*@-sizeoftype@*/
+ /*@-sizeoftype@*/
if (os->argb && PBM_ISSET(i, os->argb))
/*@innercontinue@*/ continue;
if (*os->argv[i] == '-')
@@ -670,18 +551,19 @@ static const char * findNextArg(/*@special@*/ poptContext con,
/*@innercontinue@*/ continue;
arg = os->argv[i];
if (delete_arg) {
- if (os->argb == NULL) os->argb = PBM_ALLOC(os->argc);
+ if (os->argb == NULL) os->argb = (pbm_set *)PBM_ALLOC(os->argc);
if (os->argb != NULL) /* XXX can't happen */
- PBM_SET(i, os->argb);
+ PBM_SET(i, os->argb);
}
/*@innerbreak@*/ break;
-/*@=sizeoftype@*/
+ /*@=sizeoftype@*/
}
if (os > con->optionStack) os--;
} while (arg == NULL);
return arg;
}
+/*@-boundswrite@*/
static /*@only@*/ /*@null@*/ const char *
expandNextArg(/*@special@*/ poptContext con, const char * s)
/*@uses con->optionStack, con->os,
@@ -689,13 +571,13 @@ expandNextArg(/*@special@*/ poptContext con, const char * s)
/*@modifies con @*/
{
const char * a = NULL;
+ size_t alen;
char *t, *te;
size_t tn = strlen(s) + 1;
char c;
- te = t = malloc(tn);
+ te = t = (char *)malloc(tn);;
if (t == NULL) return NULL; /* XXX can't happen */
- *t = '\0';
while ((c = *s++) != '\0') {
switch (c) {
#if 0 /* XXX can't do this */
@@ -708,17 +590,17 @@ expandNextArg(/*@special@*/ poptContext con, const char * s)
/*@switchbreak@*/ break;
/* XXX Make sure that findNextArg deletes only next arg. */
if (a == NULL) {
- if ((a = findNextArg(con, 1U, 1)) == NULL)
+ if ((a = findNextArg(con, 1, 1)) == NULL)
/*@switchbreak@*/ break;
}
- s += sizeof("#:+") - 1;
-
- tn += strlen(a);
- { size_t pos = (size_t) (te - t);
- if ((t = realloc(t, tn)) == NULL) /* XXX can't happen */
- return NULL;
- te = stpcpy(t + pos, a);
- }
+ s += 3;
+
+ alen = strlen(a);
+ tn += alen;
+ *te = '\0';
+ t = (char *)realloc(t, tn);
+ te = t + strlen(t);
+ strncpy(te, a, alen); te += alen;
continue;
/*@notreached@*/ /*@switchbreak@*/ break;
default:
@@ -726,292 +608,48 @@ expandNextArg(/*@special@*/ poptContext con, const char * s)
}
*te++ = c;
}
- *te++ = '\0';
- /* If the new string is longer than needed, shorten. */
- if ((t + tn) > te) {
-/*@-usereleased@*/ /* XXX splint can't follow the pointers. */
- if ((te = realloc(t, (size_t)(te - t))) == NULL)
- free(t);
- t = te;
-/*@=usereleased@*/
- }
+ *te = '\0';
+ t = (char *)realloc(t, strlen(t) + 1); /* XXX memory leak, hard to plug */
return t;
}
+/*@=boundswrite@*/
static void poptStripArg(/*@special@*/ poptContext con, int which)
- /*@uses con->optionStack @*/
+ /*@uses con->arg_strip, con->optionStack @*/
/*@defines con->arg_strip @*/
/*@modifies con @*/
{
-/*@-compdef -sizeoftype -usedef @*/
+ /*@-sizeoftype@*/
if (con->arg_strip == NULL)
- con->arg_strip = PBM_ALLOC(con->optionStack[0].argc);
+ con->arg_strip = (pbm_set *)PBM_ALLOC(con->optionStack[0].argc);
if (con->arg_strip != NULL) /* XXX can't happen */
PBM_SET(which, con->arg_strip);
+ /*@=sizeoftype@*/
+ /*@-compdef@*/ /* LCL: con->arg_strip udefined? */
return;
-/*@=compdef =sizeoftype =usedef @*/
-}
-
-/*@unchecked@*/
-unsigned int _poptBitsN = _POPT_BITS_N;
-/*@unchecked@*/
-unsigned int _poptBitsM = _POPT_BITS_M;
-/*@unchecked@*/
-unsigned int _poptBitsK = _POPT_BITS_K;
-
-/*@-sizeoftype@*/
-static int _poptBitsNew(/*@null@*/ poptBits *bitsp)
- /*@globals _poptBitsN, _poptBitsM, _poptBitsK @*/
- /*@modifies *bitsp, _poptBitsN, _poptBitsM, _poptBitsK @*/
-{
- if (bitsp == NULL)
- return POPT_ERROR_NULLARG;
-
- /* XXX handle negated initialization. */
- if (*bitsp == NULL) {
- if (_poptBitsN == 0) {
- _poptBitsN = _POPT_BITS_N;
- _poptBitsM = _POPT_BITS_M;
- }
- if (_poptBitsM == 0U) _poptBitsM = (3 * _poptBitsN) / 2;
- if (_poptBitsK == 0U || _poptBitsK > 32U) _poptBitsK = _POPT_BITS_K;
- *bitsp = PBM_ALLOC(_poptBitsM-1);
- }
-/*@-nullstate@*/
- return 0;
-/*@=nullstate@*/
-}
-
-int poptBitsAdd(poptBits bits, const char * s)
-{
- size_t ns = (s ? strlen(s) : 0);
- uint32_t h0 = 0;
- uint32_t h1 = 0;
-
- if (bits == NULL || ns == 0)
- return POPT_ERROR_NULLARG;
-
- poptJlu32lpair(s, ns, &h0, &h1);
-
- for (ns = 0; ns < (size_t)_poptBitsK; ns++) {
- uint32_t h = h0 + ns * h1;
- uint32_t ix = (h % _poptBitsM);
- PBM_SET(ix, bits);
- }
- return 0;
+ /*@=compdef@*/
}
-int poptBitsChk(poptBits bits, const char * s)
+int poptSaveLong(long * arg, int argInfo, long aLong)
{
- size_t ns = (s ? strlen(s) : 0);
- uint32_t h0 = 0;
- uint32_t h1 = 0;
- int rc = 1;
-
- if (bits == NULL || ns == 0)
- return POPT_ERROR_NULLARG;
-
- poptJlu32lpair(s, ns, &h0, &h1);
-
- for (ns = 0; ns < (size_t)_poptBitsK; ns++) {
- uint32_t h = h0 + ns * h1;
- uint32_t ix = (h % _poptBitsM);
- if (PBM_ISSET(ix, bits))
- continue;
- rc = 0;
- break;
- }
- return rc;
-}
-
-int poptBitsClr(poptBits bits)
-{
- static size_t nbw = (__PBM_NBITS/8);
- size_t nw = (__PBM_IX(_poptBitsM-1) + 1);
-
- if (bits == NULL)
- return POPT_ERROR_NULLARG;
- memset(bits, 0, nw * nbw);
- return 0;
-}
-
-int poptBitsDel(poptBits bits, const char * s)
-{
- size_t ns = (s ? strlen(s) : 0);
- uint32_t h0 = 0;
- uint32_t h1 = 0;
-
- if (bits == NULL || ns == 0)
- return POPT_ERROR_NULLARG;
-
- poptJlu32lpair(s, ns, &h0, &h1);
-
- for (ns = 0; ns < (size_t)_poptBitsK; ns++) {
- uint32_t h = h0 + ns * h1;
- uint32_t ix = (h % _poptBitsM);
- PBM_CLR(ix, bits);
- }
- return 0;
-}
-
-int poptBitsIntersect(poptBits *ap, const poptBits b)
-{
- __pbm_bits *abits;
- __pbm_bits *bbits;
- __pbm_bits rc = 0;
- size_t nw = (__PBM_IX(_poptBitsM-1) + 1);
- size_t i;
-
- if (ap == NULL || b == NULL || _poptBitsNew(ap))
- return POPT_ERROR_NULLARG;
- abits = __PBM_BITS(*ap);
- bbits = __PBM_BITS(b);
-
- for (i = 0; i < nw; i++) {
- abits[i] &= bbits[i];
- rc |= abits[i];
- }
- return (rc ? 1 : 0);
-}
-
-int poptBitsUnion(poptBits *ap, const poptBits b)
-{
- __pbm_bits *abits;
- __pbm_bits *bbits;
- __pbm_bits rc = 0;
- size_t nw = (__PBM_IX(_poptBitsM-1) + 1);
- size_t i;
-
- if (ap == NULL || b == NULL || _poptBitsNew(ap))
- return POPT_ERROR_NULLARG;
- abits = __PBM_BITS(*ap);
- bbits = __PBM_BITS(b);
-
- for (i = 0; i < nw; i++) {
- abits[i] |= bbits[i];
- rc |= abits[i];
- }
- return (rc ? 1 : 0);
-}
-
-int poptBitsArgs(poptContext con, poptBits *ap)
-{
- const char ** av;
- int rc = 0;
-
- if (con == NULL || ap == NULL || _poptBitsNew(ap) ||
- con->leftovers == NULL || con->numLeftovers == con->nextLeftover)
- return POPT_ERROR_NULLARG;
-
- /* some apps like [like RPM ;-) ] need this NULL terminated */
- con->leftovers[con->numLeftovers] = NULL;
-
- for (av = con->leftovers + con->nextLeftover; *av != NULL; av++) {
- if ((rc = poptBitsAdd(*ap, *av)) != 0)
- break;
- }
-/*@-nullstate@*/
- return rc;
-/*@=nullstate@*/
-}
-
-int poptSaveBits(poptBits * bitsp,
- /*@unused@*/ UNUSED(unsigned int argInfo), const char * s)
-{
- char *tbuf = NULL;
- char *t, *te;
- int rc = 0;
-
- if (bitsp == NULL || s == NULL || *s == '\0' || _poptBitsNew(bitsp))
- return POPT_ERROR_NULLARG;
-
- /* Parse comma separated attributes. */
- te = tbuf = xstrdup(s);
- while ((t = te) != NULL && *t) {
- while (*te != '\0' && *te != ',')
- te++;
- if (*te != '\0')
- *te++ = '\0';
- /* XXX Ignore empty strings. */
- if (*t == '\0')
- continue;
- /* XXX Permit negated attributes. caveat emptor: false negatives. */
- if (*t == '!') {
- t++;
- if ((rc = poptBitsChk(*bitsp, t)) > 0)
- rc = poptBitsDel(*bitsp, t);
- } else
- rc = poptBitsAdd(*bitsp, t);
- if (rc)
- break;
- }
- tbuf = _free(tbuf);
- return rc;
-}
-/*@=sizeoftype@*/
-
-int poptSaveString(const char *** argvp,
- /*@unused@*/ UNUSED(unsigned int argInfo), const char * val)
-{
- int argc = 0;
-
- if (argvp == NULL || val == NULL)
- return POPT_ERROR_NULLARG;
-
- /* XXX likely needs an upper bound on argc. */
- if (*argvp != NULL)
- while ((*argvp)[argc] != NULL)
- argc++;
-
-/*@-unqualifiedtrans -nullstate@*/ /* XXX no annotation for (*argvp) */
- if ((*argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp))) != NULL) {
- (*argvp)[argc++] = xstrdup(val);
- (*argvp)[argc ] = NULL;
- }
- return 0;
-/*@=unqualifiedtrans =nullstate@*/
-}
-
-/*@unchecked@*/
-static unsigned int seed = 0;
-
-int poptSaveLongLong(long long * arg, unsigned int argInfo, long long aLongLong)
-{
- if (arg == NULL
-#ifdef NOTYET
/* XXX Check alignment, may fail on funky platforms. */
- || (((unsigned long long)arg) & (sizeof(*arg)-1))
-#endif
- )
+ if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
return POPT_ERROR_NULLARG;
- if (aLongLong != 0 && LF_ISSET(RANDOM)) {
-#if defined(HAVE_SRANDOM)
- if (!seed) {
- srandom((unsigned)getpid());
- srandom((unsigned)random());
- }
- aLongLong = (long long)(random() % (aLongLong > 0 ? aLongLong : -aLongLong));
- aLongLong++;
-#else
- /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
- return POPT_ERROR_BADOPERATION;
-#endif
- }
- if (LF_ISSET(NOT))
- aLongLong = ~aLongLong;
- switch (LF_ISSET(LOGICALOPS)) {
+ if (argInfo & POPT_ARGFLAG_NOT)
+ aLong = ~aLong;
+ switch (argInfo & POPT_ARGFLAG_LOGICALOPS) {
case 0:
- *arg = aLongLong;
+ *arg = aLong;
break;
case POPT_ARGFLAG_OR:
- *(unsigned long long *)arg |= (unsigned long long)aLongLong;
+ *arg |= aLong;
break;
case POPT_ARGFLAG_AND:
- *(unsigned long long *)arg &= (unsigned long long)aLongLong;
+ *arg &= aLong;
break;
case POPT_ARGFLAG_XOR:
- *(unsigned long long *)arg ^= (unsigned long long)aLongLong;
+ *arg ^= aLong;
break;
default:
return POPT_ERROR_BADOPERATION;
@@ -1020,281 +658,35 @@ int poptSaveLongLong(long long * arg, unsigned int argInfo, long long aLongLong)
return 0;
}
-int poptSaveLong(long * arg, unsigned int argInfo, long aLong)
+int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong)
{
/* XXX Check alignment, may fail on funky platforms. */
if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
return POPT_ERROR_NULLARG;
- if (aLong != 0 && LF_ISSET(RANDOM)) {
-#if defined(HAVE_SRANDOM)
- if (!seed) {
- srandom((unsigned)getpid());
- srandom((unsigned)random());
- }
- aLong = random() % (aLong > 0 ? aLong : -aLong);
- aLong++;
-#else
- /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
- return POPT_ERROR_BADOPERATION;
-#endif
- }
- if (LF_ISSET(NOT))
+ if (argInfo & POPT_ARGFLAG_NOT)
aLong = ~aLong;
- switch (LF_ISSET(LOGICALOPS)) {
- case 0: *arg = aLong; break;
- case POPT_ARGFLAG_OR: *(unsigned long *)arg |= (unsigned long)aLong; break;
- case POPT_ARGFLAG_AND: *(unsigned long *)arg &= (unsigned long)aLong; break;
- case POPT_ARGFLAG_XOR: *(unsigned long *)arg ^= (unsigned long)aLong; break;
- default:
- return POPT_ERROR_BADOPERATION;
- /*@notreached@*/ break;
- }
- return 0;
-}
-
-int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong)
-{
- /* XXX Check alignment, may fail on funky platforms. */
- if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
- return POPT_ERROR_NULLARG;
-
- if (aLong != 0 && LF_ISSET(RANDOM)) {
-#if defined(HAVE_SRANDOM)
- if (!seed) {
- srandom((unsigned)getpid());
- srandom((unsigned)random());
- }
- aLong = random() % (aLong > 0 ? aLong : -aLong);
- aLong++;
-#else
- /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
- return POPT_ERROR_BADOPERATION;
-#endif
- }
- if (LF_ISSET(NOT))
- aLong = ~aLong;
- switch (LF_ISSET(LOGICALOPS)) {
- case 0: *arg = (int) aLong; break;
- case POPT_ARGFLAG_OR: *(unsigned int *)arg |= (unsigned int) aLong; break;
- case POPT_ARGFLAG_AND: *(unsigned int *)arg &= (unsigned int) aLong; break;
- case POPT_ARGFLAG_XOR: *(unsigned int *)arg ^= (unsigned int) aLong; break;
- default:
- return POPT_ERROR_BADOPERATION;
- /*@notreached@*/ break;
- }
- return 0;
-}
-
-int poptSaveShort(/*@null@*/ short * arg, unsigned int argInfo, long aLong)
-{
- /* XXX Check alignment, may fail on funky platforms. */
- if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
- return POPT_ERROR_NULLARG;
-
- if (aLong != 0 && LF_ISSET(RANDOM)) {
-#if defined(HAVE_SRANDOM)
- if (!seed) {
- srandom((unsigned)getpid());
- srandom((unsigned)random());
- }
- aLong = random() % (aLong > 0 ? aLong : -aLong);
- aLong++;
-#else
- /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
- return POPT_ERROR_BADOPERATION;
-#endif
- }
- if (LF_ISSET(NOT))
- aLong = ~aLong;
- switch (LF_ISSET(LOGICALOPS)) {
- case 0: *arg = (short) aLong;
+ switch (argInfo & POPT_ARGFLAG_LOGICALOPS) {
+ case 0:
+ *arg = aLong;
break;
- case POPT_ARGFLAG_OR: *(unsigned short *)arg |= (unsigned short) aLong;
+ case POPT_ARGFLAG_OR:
+ *arg |= aLong;
break;
- case POPT_ARGFLAG_AND: *(unsigned short *)arg &= (unsigned short) aLong;
+ case POPT_ARGFLAG_AND:
+ *arg &= aLong;
break;
- case POPT_ARGFLAG_XOR: *(unsigned short *)arg ^= (unsigned short) aLong;
+ case POPT_ARGFLAG_XOR:
+ *arg ^= aLong;
break;
- default: return POPT_ERROR_BADOPERATION;
+ default:
+ return POPT_ERROR_BADOPERATION;
/*@notreached@*/ break;
}
return 0;
}
-/**
- * Return argInfo field, handling POPT_ARGFLAG_TOGGLE overrides.
- * @param con context
- * @param opt option
- * @return argInfo
- */
-static unsigned int poptArgInfo(poptContext con, const struct poptOption * opt)
- /*@*/
-{
- unsigned int argInfo = opt->argInfo;
-
- if (con->os->argv != NULL && con->os->next > 0 && opt->longName != NULL)
- if (LF_ISSET(TOGGLE)) {
- const char * longName = con->os->argv[con->os->next-1];
- while (*longName == '-') longName++;
- /* XXX almost good enough but consider --[no]nofoo corner cases. */
- if (longName[0] != opt->longName[0] || longName[1] != opt->longName[1])
- {
- if (!LF_ISSET(XOR)) { /* XXX dont toggle with XOR */
- /* Toggle POPT_BIT_SET <=> POPT_BIT_CLR. */
- if (LF_ISSET(LOGICALOPS))
- argInfo ^= (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND);
- argInfo ^= POPT_ARGFLAG_NOT;
- }
- }
- }
- return argInfo;
-}
-
-/**
- * Parse an integer expression.
- * @retval *llp integer expression value
- * @param argInfo integer expression type
- * @param val integer expression string
- * @return 0 on success, otherwise POPT_* error.
- */
-static int poptParseInteger(long long * llp,
- /*@unused@*/ UNUSED(unsigned int argInfo),
- /*@null@*/ const char * val)
- /*@modifies *llp @*/
-{
- if (val) {
- char *end = NULL;
- *llp = strtoll(val, &end, 0);
-
- /* XXX parse scaling suffixes here. */
-
- if (!(end && *end == '\0'))
- return POPT_ERROR_BADNUMBER;
- } else
- *llp = 0;
- return 0;
-}
-
-/**
- * Save the option argument through the (*opt->arg) pointer.
- * @param con context
- * @param opt option
- * @return 0 on success, otherwise POPT_* error.
- */
-static int poptSaveArg(poptContext con, const struct poptOption * opt)
- /*@globals fileSystem, internalState @*/
- /*@modifies con, fileSystem, internalState @*/
-{
- poptArg arg = { .ptr = opt->arg };
- int rc = 0; /* assume success */
-
- switch (poptArgType(opt)) {
- case POPT_ARG_BITSET:
- /* XXX memory leak, application is responsible for free. */
- rc = poptSaveBits(arg.ptr, opt->argInfo, con->os->nextArg);
- /*@switchbreak@*/ break;
- case POPT_ARG_ARGV:
- /* XXX memory leak, application is responsible for free. */
- rc = poptSaveString(arg.ptr, opt->argInfo, con->os->nextArg);
- /*@switchbreak@*/ break;
- case POPT_ARG_STRING:
- /* XXX memory leak, application is responsible for free. */
- arg.argv[0] = (con->os->nextArg) ? xstrdup(con->os->nextArg) : NULL;
- /*@switchbreak@*/ break;
-
- case POPT_ARG_INT:
- case POPT_ARG_SHORT:
- case POPT_ARG_LONG:
- case POPT_ARG_LONGLONG:
- { unsigned int argInfo = poptArgInfo(con, opt);
- long long aNUM = 0;
-
- if ((rc = poptParseInteger(&aNUM, argInfo, con->os->nextArg)) != 0)
- break;
-
- switch (poptArgType(opt)) {
- case POPT_ARG_LONGLONG:
-/* XXX let's not demand C99 compiler flags for <limits.h> quite yet. */
-#if !defined(LLONG_MAX)
-# define LLONG_MAX 9223372036854775807LL
-# define LLONG_MIN (-LLONG_MAX - 1LL)
-#endif
- rc = !(aNUM == LLONG_MIN || aNUM == LLONG_MAX)
- ? poptSaveLongLong(arg.longlongp, argInfo, aNUM)
- : POPT_ERROR_OVERFLOW;
- /*@innerbreak@*/ break;
- case POPT_ARG_LONG:
- rc = !(aNUM < (long long)LONG_MIN || aNUM > (long long)LONG_MAX)
- ? poptSaveLong(arg.longp, argInfo, (long)aNUM)
- : POPT_ERROR_OVERFLOW;
- /*@innerbreak@*/ break;
- case POPT_ARG_INT:
- rc = !(aNUM < (long long)INT_MIN || aNUM > (long long)INT_MAX)
- ? poptSaveInt(arg.intp, argInfo, (long)aNUM)
- : POPT_ERROR_OVERFLOW;
- /*@innerbreak@*/ break;
- case POPT_ARG_SHORT:
- rc = !(aNUM < (long long)SHRT_MIN || aNUM > (long long)SHRT_MAX)
- ? poptSaveShort(arg.shortp, argInfo, (long)aNUM)
- : POPT_ERROR_OVERFLOW;
- /*@innerbreak@*/ break;
- }
- } /*@switchbreak@*/ break;
-
- case POPT_ARG_FLOAT:
- case POPT_ARG_DOUBLE:
- { char *end = NULL;
- double aDouble = 0.0;
-
- if (con->os->nextArg) {
-/*@-mods@*/
- int saveerrno = errno;
- errno = 0;
- aDouble = strtod(con->os->nextArg, &end);
- if (errno == ERANGE) {
- rc = POPT_ERROR_OVERFLOW;
- break;
- }
- errno = saveerrno;
-/*@=mods@*/
- if (*end != '\0') {
- rc = POPT_ERROR_BADNUMBER;
- break;
- }
- }
-
- switch (poptArgType(opt)) {
- case POPT_ARG_DOUBLE:
- arg.doublep[0] = aDouble;
- /*@innerbreak@*/ break;
- case POPT_ARG_FLOAT:
-#if !defined(DBL_EPSILON) && !defined(__LCLINT__)
-#define DBL_EPSILON 2.2204460492503131e-16
-#endif
-#define POPT_ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a))
- if ((FLT_MIN - POPT_ABS(aDouble)) > DBL_EPSILON
- || (POPT_ABS(aDouble) - FLT_MAX) > DBL_EPSILON)
- rc = POPT_ERROR_OVERFLOW;
- else
- arg.floatp[0] = (float) aDouble;
- /*@innerbreak@*/ break;
- }
- } /*@switchbreak@*/ break;
- case POPT_ARG_MAINCALL:
-/*@-assignexpose -type@*/
- con->maincall = opt->arg;
-/*@=assignexpose =type@*/
- /*@switchbreak@*/ break;
- default:
- fprintf(stdout, POPT_("option type (%u) not implemented in popt\n"),
- poptArgType(opt));
- exit(EXIT_FAILURE);
- /*@notreached@*/ /*@switchbreak@*/ break;
- }
- return rc;
-}
-
+/*@-boundswrite@*/
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
int poptGetNextOpt(poptContext con)
{
@@ -1316,31 +708,24 @@ int poptGetNextOpt(poptContext con)
cleanOSE(con->os--);
}
if (!con->os->nextCharArg && con->os->next == con->os->argc) {
+ /*@-internalglobs@*/
invokeCallbacksPOST(con, con->options);
-
- if (con->maincall) {
- /*@-noeffectuncon @*/
- (void) (*con->maincall) (con->finalArgvCount, con->finalArgv);
- /*@=noeffectuncon @*/
- return -1;
- }
-
+ /*@=internalglobs@*/
if (con->doExec) return execCommand(con);
return -1;
}
/* Process next long option */
if (!con->os->nextCharArg) {
- const char * optString;
- size_t optStringLen;
+ char * localOptString, * optString;
int thisopt;
-/*@-sizeoftype@*/
+ /*@-sizeoftype@*/
if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) {
con->os->next++;
continue;
}
-/*@=sizeoftype@*/
+ /*@=sizeoftype@*/
thisopt = con->os->next;
if (con->os->argv != NULL) /* XXX can't happen */
origOptString = con->os->argv[con->os->next++];
@@ -1348,9 +733,7 @@ int poptGetNextOpt(poptContext con)
if (origOptString == NULL) /* XXX can't happen */
return POPT_ERROR_BADOPT;
- if (con->restLeftover || *origOptString != '-' ||
- (*origOptString == '-' && origOptString[1] == '\0'))
- {
+ if (con->restLeftover || *origOptString != '-') {
if (con->flags & POPT_CONTEXT_POSIXMEHARDER)
con->restLeftover = 1;
if (con->flags & POPT_CONTEXT_ARG_OPTS) {
@@ -1363,7 +746,9 @@ int poptGetNextOpt(poptContext con)
}
/* Make a copy we can hack at */
- optString = origOptString;
+ localOptString = optString =
+ strcpy((char *)alloca(strlen(origOptString) + 1),
+ origOptString);
if (optString[0] == '\0')
return POPT_ERROR_BADOPT;
@@ -1372,42 +757,42 @@ int poptGetNextOpt(poptContext con)
con->restLeftover = 1;
continue;
} else {
- const char *oe;
- unsigned int argInfo = 0;
+ char *oe;
+ int singleDash;
optString++;
if (*optString == '-')
- optString++;
+ singleDash = 0, optString++;
else
- argInfo |= POPT_ARGFLAG_ONEDASH;
-
- /* Check for "--long=arg" option. */
- for (oe = optString; *oe && *oe != '='; oe++)
- {};
- optStringLen = (size_t)(oe - optString);
- if (*oe == '=')
- longArg = oe + 1;
+ singleDash = 1;
/* XXX aliases with arg substitution need "--alias=arg" */
- if (handleAlias(con, optString, optStringLen, '\0', longArg)) {
- longArg = NULL;
+ if (handleAlias(con, optString, '\0', NULL))
continue;
- }
if (handleExec(con, optString, '\0'))
continue;
- opt = findOption(con->options, optString, optStringLen, '\0', &cb, &cbData,
- argInfo);
- if (!opt && !LF_ISSET(ONEDASH))
+ /* Check for "--long=arg" option. */
+ for (oe = optString; *oe && *oe != '='; oe++)
+ {};
+ if (*oe == '=') {
+ *oe++ = '\0';
+ /* XXX longArg is mapped back to persistent storage. */
+ longArg = origOptString + (oe - localOptString);
+ }
+
+ opt = findOption(con->options, optString, '\0', &cb, &cbData,
+ singleDash);
+ if (!opt && !singleDash)
return POPT_ERROR_BADOPT;
}
if (!opt) {
con->os->nextCharArg = origOptString + 1;
- longArg = NULL;
} else {
- if (con->os == con->optionStack && F_ISSET(opt, STRIP))
+ if (con->os == con->optionStack &&
+ opt->argInfo & POPT_ARGFLAG_STRIP)
{
canstrip = 1;
poptStripArg(con, thisopt);
@@ -1417,64 +802,65 @@ int poptGetNextOpt(poptContext con)
}
/* Process next short option */
+ /*@-branchstate@*/ /* FIX: W2DO? */
if (con->os->nextCharArg) {
- const char * nextCharArg = con->os->nextCharArg;
+ origOptString = con->os->nextCharArg;
con->os->nextCharArg = NULL;
- if (handleAlias(con, NULL, 0, *nextCharArg, nextCharArg + 1))
+ if (handleAlias(con, NULL, *origOptString, origOptString + 1))
continue;
- if (handleExec(con, NULL, *nextCharArg)) {
+ if (handleExec(con, NULL, *origOptString)) {
/* Restore rest of short options for further processing */
- nextCharArg++;
- if (*nextCharArg != '\0')
- con->os->nextCharArg = nextCharArg;
+ origOptString++;
+ if (*origOptString != '\0')
+ con->os->nextCharArg = origOptString;
continue;
}
- opt = findOption(con->options, NULL, 0, *nextCharArg, &cb,
+ opt = findOption(con->options, NULL, *origOptString, &cb,
&cbData, 0);
if (!opt)
return POPT_ERROR_BADOPT;
shorty = 1;
- nextCharArg++;
- if (*nextCharArg != '\0')
- con->os->nextCharArg = nextCharArg + (int)(*nextCharArg == '=');
+ origOptString++;
+ if (*origOptString != '\0')
+ con->os->nextCharArg = origOptString;
}
+ /*@=branchstate@*/
if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */
- if (opt->arg && poptArgType(opt) == POPT_ARG_NONE) {
- unsigned int argInfo = poptArgInfo(con, opt);
- if (poptSaveInt((int *)opt->arg, argInfo, 1L))
+ if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) {
+ if (poptSaveInt((int *)opt->arg, opt->argInfo, 1L))
return POPT_ERROR_BADOPERATION;
- } else if (poptArgType(opt) == POPT_ARG_VAL) {
+ } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) {
if (opt->arg) {
- unsigned int argInfo = poptArgInfo(con, opt);
- if (poptSaveInt((int *)opt->arg, argInfo, (long)opt->val))
+ if (poptSaveInt((int *)opt->arg, opt->argInfo, (long)opt->val))
return POPT_ERROR_BADOPERATION;
}
- } else if (poptArgType(opt) != POPT_ARG_NONE) {
- int rc;
-
- con->os->nextArg = _free(con->os->nextArg);
+ } else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) {
+ con->os->nextArg = (const char *)_free(con->os->nextArg);
+ /*@-usedef@*/ /* FIX: W2DO? */
if (longArg) {
+ /*@=usedef@*/
longArg = expandNextArg(con, longArg);
- con->os->nextArg = (char *) longArg;
+ con->os->nextArg = longArg;
} else if (con->os->nextCharArg) {
longArg = expandNextArg(con, con->os->nextCharArg);
- con->os->nextArg = (char *) longArg;
+ con->os->nextArg = longArg;
con->os->nextCharArg = NULL;
} else {
while (con->os->next == con->os->argc &&
- con->os > con->optionStack)
- {
+ con->os > con->optionStack) {
cleanOSE(con->os--);
}
if (con->os->next == con->os->argc) {
- if (!F_ISSET(opt, OPTIONAL))
+ if (!(opt->argInfo & POPT_ARGFLAG_OPTIONAL))
+ /*@-compdef@*/ /* FIX: con->os->argv not defined */
return POPT_ERROR_NOARG;
+ /*@=compdef@*/
con->os->nextArg = NULL;
} else {
@@ -1482,81 +868,149 @@ int poptGetNextOpt(poptContext con)
* Make sure this isn't part of a short arg or the
* result of an alias expansion.
*/
- if (con->os == con->optionStack
- && F_ISSET(opt, STRIP) && canstrip)
- {
+ if (con->os == con->optionStack &&
+ (opt->argInfo & POPT_ARGFLAG_STRIP) &&
+ canstrip) {
poptStripArg(con, con->os->next);
}
if (con->os->argv != NULL) { /* XXX can't happen */
- if (F_ISSET(opt, OPTIONAL) &&
- con->os->argv[con->os->next][0] == '-') {
- con->os->nextArg = NULL;
- } else {
- /* XXX watchout: subtle side-effects live here. */
- longArg = con->os->argv[con->os->next++];
- longArg = expandNextArg(con, longArg);
- con->os->nextArg = (char *) longArg;
- }
+ /* XXX watchout: subtle side-effects live here. */
+ longArg = con->os->argv[con->os->next++];
+ longArg = expandNextArg(con, longArg);
+ con->os->nextArg = longArg;
}
}
}
longArg = NULL;
- /* Save the option argument through a (*opt->arg) pointer. */
- if (opt->arg != NULL && (rc = poptSaveArg(con, opt)) != 0)
- return rc;
+ if (opt->arg) {
+ switch (opt->argInfo & POPT_ARG_MASK) {
+ case POPT_ARG_STRING:
+ /* XXX memory leak, hard to plug */
+ *((const char **) opt->arg) = (con->os->nextArg)
+ ? xstrdup(con->os->nextArg) : NULL;
+ /*@switchbreak@*/ break;
+
+ case POPT_ARG_INT:
+ case POPT_ARG_LONG:
+ { long aLong = 0;
+ char *end;
+
+ if (con->os->nextArg) {
+ aLong = strtol(con->os->nextArg, &end, 0);
+ if (!(end && *end == '\0'))
+ return POPT_ERROR_BADNUMBER;
+ }
+
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) {
+ if (aLong == LONG_MIN || aLong == LONG_MAX)
+ return POPT_ERROR_OVERFLOW;
+ if (poptSaveLong((long *)opt->arg, opt->argInfo, aLong))
+ return POPT_ERROR_BADOPERATION;
+ } else {
+ if (aLong > INT_MAX || aLong < INT_MIN)
+ return POPT_ERROR_OVERFLOW;
+ if (poptSaveInt((int *)opt->arg, opt->argInfo, aLong))
+ return POPT_ERROR_BADOPERATION;
+ }
+ } /*@switchbreak@*/ break;
+
+ case POPT_ARG_FLOAT:
+ case POPT_ARG_DOUBLE:
+ { double aDouble = 0.0;
+ char *end;
+
+ if (con->os->nextArg) {
+ /*@-mods@*/
+ int saveerrno = errno;
+ errno = 0;
+ aDouble = strtod(con->os->nextArg, &end);
+ if (errno == ERANGE)
+ return POPT_ERROR_OVERFLOW;
+ errno = saveerrno;
+ /*@=mods@*/
+ if (*end != '\0')
+ return POPT_ERROR_BADNUMBER;
+ }
+
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_DOUBLE) {
+ *((double *) opt->arg) = aDouble;
+ } else {
+#ifndef _ABS
+#define _ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a))
+#endif
+ if ((_ABS(aDouble) - FLT_MAX) > DBL_EPSILON)
+ return POPT_ERROR_OVERFLOW;
+ if ((FLT_MIN - _ABS(aDouble)) > DBL_EPSILON)
+ return POPT_ERROR_OVERFLOW;
+ *((float *) opt->arg) = aDouble;
+ }
+ } /*@switchbreak@*/ break;
+ default:
+ fprintf(stdout,
+ POPT_("option type (%d) not implemented in popt\n"),
+ (opt->argInfo & POPT_ARG_MASK));
+ exit(EXIT_FAILURE);
+ /*@notreached@*/ /*@switchbreak@*/ break;
+ }
+ }
}
- if (cb)
+ if (cb) {
+ /*@-internalglobs@*/
invokeCallbacksOPTION(con, con->options, opt, cbData, shorty);
- else if (opt->val && (poptArgType(opt) != POPT_ARG_VAL))
+ /*@=internalglobs@*/
+ } else if (opt->val && ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL))
done = 1;
if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) {
con->finalArgvAlloced += 10;
- con->finalArgv = realloc(con->finalArgv,
+ con->finalArgv = (const char **)realloc(con->finalArgv,
sizeof(*con->finalArgv) * con->finalArgvAlloced);
}
if (con->finalArgv != NULL)
- { char *s = malloc((opt->longName ? strlen(opt->longName) : 0) + sizeof("--"));
+ { char *s = (char *)malloc(
+ (opt->longName ? strlen(opt->longName) : 0) + 3);
if (s != NULL) { /* XXX can't happen */
+ if (opt->longName)
+ sprintf(s, "%s%s",
+ ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
+ opt->longName);
+ else
+ sprintf(s, "-%c", opt->shortName);
con->finalArgv[con->finalArgvCount++] = s;
- *s++ = '-';
- if (opt->longName) {
- if (!F_ISSET(opt, ONEDASH))
- *s++ = '-';
- s = stpcpy(s, opt->longName);
- } else {
- *s++ = opt->shortName;
- *s = '\0';
- }
} else
con->finalArgv[con->finalArgvCount++] = NULL;
}
- if (opt->arg && poptArgType(opt) == POPT_ARG_NONE)
+ if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE)
/*@-ifempty@*/ ; /*@=ifempty@*/
- else if (poptArgType(opt) == POPT_ARG_VAL)
+ else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL)
/*@-ifempty@*/ ; /*@=ifempty@*/
- else if (poptArgType(opt) != POPT_ARG_NONE) {
- if (con->finalArgv != NULL && con->os->nextArg != NULL)
+ else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) {
+ if (con->finalArgv != NULL && con->os->nextArg)
con->finalArgv[con->finalArgvCount++] =
+ /*@-nullpass@*/ /* LCL: con->os->nextArg != NULL */
xstrdup(con->os->nextArg);
+ /*@=nullpass@*/
}
}
return (opt ? opt->val : -1); /* XXX can't happen */
}
+/*@=boundswrite@*/
-char * poptGetOptArg(poptContext con)
+const char * poptGetOptArg(poptContext con)
{
- char * ret = NULL;
+ const char * ret = NULL;
+ /*@-branchstate@*/
if (con) {
ret = con->os->nextArg;
con->os->nextArg = NULL;
}
+ /*@=branchstate@*/
return ret;
}
@@ -1576,6 +1030,7 @@ const char * poptPeekArg(poptContext con)
return ret;
}
+/*@-boundswrite@*/
const char ** poptGetArgs(poptContext con)
{
if (con == NULL ||
@@ -1585,59 +1040,60 @@ const char ** poptGetArgs(poptContext con)
/* some apps like [like RPM ;-) ] need this NULL terminated */
con->leftovers[con->numLeftovers] = NULL;
-/*@-nullret -nullstate @*/ /* FIX: typedef double indirection. */
+ /*@-nullret -nullstate @*/ /* FIX: typedef double indirection. */
return (con->leftovers + con->nextLeftover);
-/*@=nullret =nullstate @*/
-}
-
-static /*@null@*/
-poptItem poptFreeItems(/*@only@*/ /*@null@*/ poptItem items, int nitems)
- /*@modifies items @*/
-{
- if (items != NULL) {
- poptItem item = items;
- while (--nitems >= 0) {
-/*@-modobserver -observertrans -dependenttrans@*/
- item->option.longName = _free(item->option.longName);
- item->option.descrip = _free(item->option.descrip);
- item->option.argDescrip = _free(item->option.argDescrip);
-/*@=modobserver =observertrans =dependenttrans@*/
- item->argv = _free(item->argv);
- item++;
- }
- items = _free(items);
- }
- return NULL;
+ /*@=nullret =nullstate @*/
}
+/*@=boundswrite@*/
poptContext poptFreeContext(poptContext con)
{
+ poptItem item;
+ int i;
+
if (con == NULL) return con;
poptResetContext(con);
- con->os->argb = _free(con->os->argb);
+ con->os->argb = (pbm_set *)_free(con->os->argb);
- con->aliases = poptFreeItems(con->aliases, con->numAliases);
- con->numAliases = 0;
-
- con->execs = poptFreeItems(con->execs, con->numExecs);
- con->numExecs = 0;
+ if (con->aliases != NULL)
+ for (i = 0; i < con->numAliases; i++) {
+ item = con->aliases + i;
+ /*@-modobserver -observertrans -dependenttrans@*/
+ item->option.longName = (const char *)_free(item->option.longName);
+ item->option.descrip = (const char *)_free(item->option.descrip);
+ item->option.argDescrip = (const char *)_free(item->option.argDescrip);
+ /*@=modobserver =observertrans =dependenttrans@*/
+ item->argv = (const char **)_free(item->argv);
+ }
+ con->aliases = (poptItem)_free(con->aliases);
- con->leftovers = _free(con->leftovers);
- con->finalArgv = _free(con->finalArgv);
- con->appName = _free(con->appName);
- con->otherHelp = _free(con->otherHelp);
- con->execPath = _free(con->execPath);
- con->arg_strip = PBM_FREE(con->arg_strip);
+ if (con->execs != NULL)
+ for (i = 0; i < con->numExecs; i++) {
+ item = con->execs + i;
+ /*@-modobserver -observertrans -dependenttrans@*/
+ item->option.longName = (const char *)_free(item->option.longName);
+ item->option.descrip = (const char *)_free(item->option.descrip);
+ item->option.argDescrip = (const char *)_free(item->option.argDescrip);
+ /*@=modobserver =observertrans =dependenttrans@*/
+ item->argv = (const char **)_free(item->argv);
+ }
+ con->execs = (poptItem)_free(con->execs);
+
+ con->leftovers = (const char **)_free(con->leftovers);
+ con->finalArgv = (const char **)_free(con->finalArgv);
+ con->appName = (const char *)_free(con->appName);
+ con->otherHelp = (const char *)_free(con->otherHelp);
+ con->execPath = (const char *)_free(con->execPath);
+ con->arg_strip = (pbm_set *)PBM_FREE(con->arg_strip);
- con = _free(con);
+ con = (poptContext)_free(con);
return con;
}
int poptAddAlias(poptContext con, struct poptAlias alias,
- /*@unused@*/ UNUSED(int flags))
+ /*@unused@*/ int flags)
{
- struct poptItem_s item_buf;
- poptItem item = &item_buf;
+ poptItem item = (poptItem)alloca(sizeof(*item));
memset(item, 0, sizeof(*item));
item->option.longName = alias.longName;
item->option.shortName = alias.shortName;
@@ -1651,6 +1107,8 @@ int poptAddAlias(poptContext con, struct poptAlias alias,
return poptAddItem(con, item, 0);
}
+/*@-boundswrite@*/
+/*@-mustmod@*/ /* LCL: con not modified? */
int poptAddItem(poptContext con, poptItem newItem, int flags)
{
poptItem * items, item;
@@ -1670,7 +1128,7 @@ int poptAddItem(poptContext con, poptItem newItem, int flags)
/*@notreached@*/ break;
}
- *items = realloc((*items), ((*nitems) + 1) * sizeof(**items));
+ *items = (poptItem)realloc((*items), ((*nitems) + 1) * sizeof(**items));
if ((*items) == NULL)
return 1;
@@ -1693,18 +1151,22 @@ int poptAddItem(poptContext con, poptItem newItem, int flags)
return 0;
}
+/*@=mustmod@*/
+/*@=boundswrite@*/
-const char * poptBadOption(poptContext con, unsigned int flags)
+const char * poptBadOption(poptContext con, int flags)
{
struct optionStackEntry * os = NULL;
if (con != NULL)
os = (flags & POPT_BADOPTION_NOALIAS) ? con->optionStack : con->os;
- return (os != NULL && os->argv != NULL ? os->argv[os->next - 1] : NULL);
+ /*@-nullderef@*/ /* LCL: os->argv != NULL */
+ return (os && os->argv ? os->argv[os->next - 1] : NULL);
+ /*@=nullderef@*/
}
-const char * poptStrerror(const int error)
+const char *poptStrerror(const int error)
{
switch (error) {
case POPT_ERROR_NOARG:
@@ -1725,8 +1187,6 @@ const char * poptStrerror(const int error)
return POPT_("number too large or too small");
case POPT_ERROR_MALLOC:
return POPT_("memory allocation failed");
- case POPT_ERROR_BADCONFIG:
- return POPT_("config file failed sanity test");
case POPT_ERROR_ERRNO:
return strerror(errno);
default:
@@ -1762,13 +1222,14 @@ const char * poptGetInvocationName(poptContext con)
return (con->os->argv ? con->os->argv[0] : "");
}
+/*@-boundswrite@*/
int poptStrippedArgv(poptContext con, int argc, char ** argv)
{
int numargs = argc;
int j = 1;
int i;
-/*@-sizeoftype@*/
+ /*@-sizeoftype@*/
if (con->arg_strip)
for (i = 1; i < argc; i++) {
if (PBM_ISSET(i, con->arg_strip))
@@ -1781,7 +1242,8 @@ int poptStrippedArgv(poptContext con, int argc, char ** argv)
argv[j] = (j < numargs) ? argv[i] : NULL;
j++;
}
-/*@=sizeoftype@*/
+ /*@=sizeoftype@*/
return numargs;
}
+/*@=boundswrite@*/
diff --git a/third_party/popt/popt.h b/third_party/popt/popt.h
index a12d143..c60ae29 100644
--- a/third_party/popt/popt.h
+++ b/third_party/popt/popt.h
@@ -17,49 +17,41 @@
* \name Arg type identifiers
*/
/*@{*/
-#define POPT_ARG_NONE 0U /*!< no arg */
-#define POPT_ARG_STRING 1U /*!< arg will be saved as string */
-#define POPT_ARG_INT 2U /*!< arg ==> int */
-#define POPT_ARG_LONG 3U /*!< arg ==> long */
-#define POPT_ARG_INCLUDE_TABLE 4U /*!< arg points to table */
-#define POPT_ARG_CALLBACK 5U /*!< table-wide callback... must be
+#define POPT_ARG_NONE 0 /*!< no arg */
+#define POPT_ARG_STRING 1 /*!< arg will be saved as string */
+#define POPT_ARG_INT 2 /*!< arg will be converted to int */
+#define POPT_ARG_LONG 3 /*!< arg will be converted to long */
+#define POPT_ARG_INCLUDE_TABLE 4 /*!< arg points to table */
+#define POPT_ARG_CALLBACK 5 /*!< table-wide callback... must be
set first in table; arg points
to callback, descrip points to
callback data to pass */
-#define POPT_ARG_INTL_DOMAIN 6U /*!< set the translation domain
+#define POPT_ARG_INTL_DOMAIN 6 /*!< set the translation domain
for this table and any
included tables; arg points
to the domain string */
-#define POPT_ARG_VAL 7U /*!< arg should take value val */
-#define POPT_ARG_FLOAT 8U /*!< arg ==> float */
-#define POPT_ARG_DOUBLE 9U /*!< arg ==> double */
-#define POPT_ARG_LONGLONG 10U /*!< arg ==> long long */
-
-#define POPT_ARG_MAINCALL 16U+11U /*!< EXPERIMENTAL: return (*arg) (argc, argv) */
-#define POPT_ARG_ARGV 12U /*!< dupe'd arg appended to realloc'd argv array. */
-#define POPT_ARG_SHORT 13U /*!< arg ==> short */
-#define POPT_ARG_BITSET 16U+14U /*!< arg ==> bit set */
-
-#define POPT_ARG_MASK 0x000000FFU
-#define POPT_GROUP_MASK 0x0000FF00U
+#define POPT_ARG_VAL 7 /*!< arg should take value val */
+#define POPT_ARG_FLOAT 8 /*!< arg will be converted to float */
+#define POPT_ARG_DOUBLE 9 /*!< arg will be converted to double */
+#define POPT_ARG_MASK 0x0000FFFF
/*@}*/
/** \ingroup popt
* \name Arg modifiers
*/
/*@{*/
-#define POPT_ARGFLAG_ONEDASH 0x80000000U /*!< allow -longoption */
-#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000U /*!< don't show in help/usage */
-#define POPT_ARGFLAG_STRIP 0x20000000U /*!< strip this arg from argv(only applies to long args) */
-#define POPT_ARGFLAG_OPTIONAL 0x10000000U /*!< arg may be missing */
-
-#define POPT_ARGFLAG_OR 0x08000000U /*!< arg will be or'ed */
-#define POPT_ARGFLAG_NOR 0x09000000U /*!< arg will be nor'ed */
-#define POPT_ARGFLAG_AND 0x04000000U /*!< arg will be and'ed */
-#define POPT_ARGFLAG_NAND 0x05000000U /*!< arg will be nand'ed */
-#define POPT_ARGFLAG_XOR 0x02000000U /*!< arg will be xor'ed */
-#define POPT_ARGFLAG_NOT 0x01000000U /*!< arg will be negated */
+#define POPT_ARGFLAG_ONEDASH 0x80000000 /*!< allow -longoption */
+#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /*!< don't show in help/usage */
+#define POPT_ARGFLAG_STRIP 0x20000000 /*!< strip this arg from argv(only applies to long args) */
+#define POPT_ARGFLAG_OPTIONAL 0x10000000 /*!< arg may be missing */
+
+#define POPT_ARGFLAG_OR 0x08000000 /*!< arg will be or'ed */
+#define POPT_ARGFLAG_NOR 0x09000000 /*!< arg will be nor'ed */
+#define POPT_ARGFLAG_AND 0x04000000 /*!< arg will be and'ed */
+#define POPT_ARGFLAG_NAND 0x05000000 /*!< arg will be nand'ed */
+#define POPT_ARGFLAG_XOR 0x02000000 /*!< arg will be xor'ed */
+#define POPT_ARGFLAG_NOT 0x01000000 /*!< arg will be negated */
#define POPT_ARGFLAG_LOGICALOPS \
(POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR)
@@ -68,9 +60,7 @@
#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND)
/*!< clear arg bit(s) */
-#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000U /*!< show default value in --help */
-#define POPT_ARGFLAG_RANDOM 0x00400000U /*!< random value in [1,arg] */
-#define POPT_ARGFLAG_TOGGLE 0x00200000U /*!< permit --[no]opt prefix toggle */
+#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000 /*!< show default value in --help */
/*@}*/
@@ -78,12 +68,12 @@
* \name Callback modifiers
*/
/*@{*/
-#define POPT_CBFLAG_PRE 0x80000000U /*!< call the callback before parse */
-#define POPT_CBFLAG_POST 0x40000000U /*!< call the callback after parse */
-#define POPT_CBFLAG_INC_DATA 0x20000000U /*!< use data from the include line,
+#define POPT_CBFLAG_PRE 0x80000000 /*!< call the callback before parse */
+#define POPT_CBFLAG_POST 0x40000000 /*!< call the callback after parse */
+#define POPT_CBFLAG_INC_DATA 0x20000000 /*!< use data from the include line,
not the subtable */
-#define POPT_CBFLAG_SKIPOPTION 0x10000000U /*!< don't callback with option */
-#define POPT_CBFLAG_CONTINUE 0x08000000U /*!< continue callbacks with option */
+#define POPT_CBFLAG_SKIPOPTION 0x10000000 /*!< don't callback with option */
+#define POPT_CBFLAG_CONTINUE 0x08000000 /*!< continue callbacks with option */
/*@}*/
/** \ingroup popt
@@ -93,31 +83,30 @@
#define POPT_ERROR_NOARG -10 /*!< missing argument */
#define POPT_ERROR_BADOPT -11 /*!< unknown option */
#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */
-#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */
+#define POPT_ERROR_BADQUOTE -15 /*!< error in parameter quoting */
#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */
#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */
#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */
#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */
#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */
#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */
-#define POPT_ERROR_BADCONFIG -22 /*!< config file failed sanity test */
/*@}*/
/** \ingroup popt
* \name poptBadOption() flags
*/
/*@{*/
-#define POPT_BADOPTION_NOALIAS (1U << 0) /*!< don't go into an alias */
+#define POPT_BADOPTION_NOALIAS (1 << 0) /*!< don't go into an alias */
/*@}*/
/** \ingroup popt
* \name poptGetContext() flags
*/
/*@{*/
-#define POPT_CONTEXT_NO_EXEC (1U << 0) /*!< ignore exec expansions */
-#define POPT_CONTEXT_KEEP_FIRST (1U << 1) /*!< pay attention to argv[0] */
-#define POPT_CONTEXT_POSIXMEHARDER (1U << 2) /*!< options can't follow args */
-#define POPT_CONTEXT_ARG_OPTS (1U << 4) /*!< return args as options with value 0 */
+#define POPT_CONTEXT_NO_EXEC (1 << 0) /*!< ignore exec expansions */
+#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /*!< pay attention to argv[0] */
+#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /*!< options can't follow args */
+#define POPT_CONTEXT_ARG_OPTS (1 << 4) /*!< return args as options with value 0 */
/*@}*/
/** \ingroup popt
@@ -125,8 +114,8 @@
struct poptOption {
/*@observer@*/ /*@null@*/
const char * longName; /*!< may be NULL */
- char shortName; /*!< may be NUL */
- unsigned int argInfo;
+ char shortName; /*!< may be '\0' */
+ int argInfo;
/*@shared@*/ /*@null@*/
void * arg; /*!< depends on argInfo */
int val; /*!< 0 means don't return, just update flag */
@@ -142,7 +131,7 @@ struct poptOption {
struct poptAlias {
/*@owned@*/ /*@null@*/
const char * longName; /*!< may be NULL */
- char shortName; /*!< may be NUL */
+ char shortName; /*!< may be '\0' */
int argc;
/*@owned@*/
const char ** argv; /*!< must be free()able */
@@ -182,16 +171,10 @@ extern struct poptOption poptAliasOptions[];
/*@unchecked@*/ /*@observer@*/
extern struct poptOption poptHelpOptions[];
/*@=exportvar@*/
-
-/*@-exportvar@*/
-/*@unchecked@*/ /*@observer@*/
-extern struct poptOption * poptHelpOptionsI18N;
-/*@=exportvar@*/
-
#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \
0, "Help options:", NULL },
-#define POPT_TABLEEND { NULL, '\0', 0, NULL, 0, NULL, NULL }
+#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
/*@}*/
/** \ingroup popt
@@ -208,8 +191,6 @@ typedef struct poptOption * poptOption;
/*@=exporttype =typeuse@*/
#endif
-/** \ingroup popt
- */
/*@-exportconst@*/
enum poptCallbackReason {
POPT_CALLBACK_REASON_PRE = 0,
@@ -236,17 +217,7 @@ typedef void (*poptCallbackType) (poptContext con,
/*@null@*/ const struct poptOption * opt,
/*@null@*/ const char * arg,
/*@null@*/ const void * data)
- /*@globals internalState @*/
- /*@modifies internalState @*/;
-
-/** \ingroup popt
- * Destroy context.
- * @param con context
- * @return NULL always
- */
-/*@null@*/
-poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con)
- /*@modifies con @*/;
+ /*@*/;
/** \ingroup popt
* Initialize popt context.
@@ -257,39 +228,12 @@ poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con)
* @param flags or'd POPT_CONTEXT_* bits
* @return initialized popt context
*/
-/*@only@*/ /*@null@*/
-poptContext poptGetContext(
+/*@only@*/ /*@null@*/ poptContext poptGetContext(
/*@dependent@*/ /*@keep@*/ const char * name,
int argc, /*@dependent@*/ /*@keep@*/ const char ** argv,
/*@dependent@*/ /*@keep@*/ const struct poptOption * options,
- unsigned int flags)
- /*@globals internalState @*/
- /*@modifies internalState @*/;
-
-/** \ingroup popt
- * Destroy context (alternative implementation).
- * @param con context
- * @return NULL always
- */
-/*@null@*/
-poptContext poptFini( /*@only@*/ /*@null@*/ poptContext con)
- /*@modifies con @*/;
-
-/** \ingroup popt
- * Initialize popt context (alternative implementation).
- * This routine does poptGetContext() and then poptReadConfigFiles().
- * @param argc no. of arguments
- * @param argv argument array
- * @param options address of popt option table
- * @param configPaths colon separated file path(s) to read.
- * @return initialized popt context (NULL on error).
- */
-/*@only@*/ /*@null@*/ /*@unused@*/
-poptContext poptInit(int argc, /*@dependent@*/ /*@keep@*/ const char ** argv,
- /*@dependent@*/ /*@keep@*/ const struct poptOption * options,
- /*@null@*/ const char * configPaths)
- /*@globals fileSystem, internalState @*/
- /*@modifies fileSystem, internalState @*/;
+ int flags)
+ /*@*/;
/** \ingroup popt
* Reinitialize popt context.
@@ -313,8 +257,7 @@ int poptGetNextOpt(/*@null@*/poptContext con)
* @param con context
* @return option argument, NULL if no argument is available
*/
-/*@observer@*/ /*@null@*/ /*@unused@*/
-char * poptGetOptArg(/*@null@*/poptContext con)
+/*@observer@*/ /*@null@*/ const char * poptGetOptArg(/*@null@*/poptContext con)
/*@modifies con @*/;
/** \ingroup popt
@@ -322,8 +265,7 @@ char * poptGetOptArg(/*@null@*/poptContext con)
* @param con context
* @return next argument, NULL if no argument is available
*/
-/*@observer@*/ /*@null@*/ /*@unused@*/
-const char * poptGetArg(/*@null@*/poptContext con)
+/*@observer@*/ /*@null@*/ const char * poptGetArg(/*@null@*/poptContext con)
/*@modifies con @*/;
/** \ingroup popt
@@ -331,8 +273,7 @@ const char * poptGetArg(/*@null@*/poptContext con)
* @param con context
* @return current argument, NULL if no argument is available
*/
-/*@observer@*/ /*@null@*/ /*@unused@*/
-const char * poptPeekArg(/*@null@*/poptContext con)
+/*@observer@*/ /*@null@*/ const char * poptPeekArg(/*@null@*/poptContext con)
/*@*/;
/** \ingroup popt
@@ -340,8 +281,7 @@ const char * poptPeekArg(/*@null@*/poptContext con)
* @param con context
* @return argument array, NULL terminated
*/
-/*@observer@*/ /*@null@*/
-const char ** poptGetArgs(/*@null@*/poptContext con)
+/*@observer@*/ /*@null@*/ const char ** poptGetArgs(/*@null@*/poptContext con)
/*@modifies con @*/;
/** \ingroup popt
@@ -350,17 +290,23 @@ const char ** poptGetArgs(/*@null@*/poptContext con)
* @param flags
* @return offending option
*/
-/*@observer@*/
-const char * poptBadOption(/*@null@*/poptContext con, unsigned int flags)
+/*@observer@*/ const char * poptBadOption(/*@null@*/poptContext con, int flags)
/*@*/;
/** \ingroup popt
+ * Destroy context.
+ * @param con context
+ * @return NULL always
+ */
+/*@null@*/ poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con)
+ /*@modifies con @*/;
+
+/** \ingroup popt
* Add arguments to context.
* @param con context
* @param argv argument array, NULL terminated
* @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure
*/
-/*@unused@*/
int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv)
/*@modifies con @*/;
@@ -388,52 +334,15 @@ int poptAddItem(poptContext con, poptItem newItem, int flags)
/*@modifies con @*/;
/** \ingroup popt
- * Perform sanity checks on a file path.
- * @param fn file name
- * @return 0 on OK, 1 on NOTOK.
- */
-int poptSaneFile(const char * fn)
- /*@globals errno, internalState @*/
- /*@modifies errno, internalState @*/;
-
-/**
- * Read a file into a buffer.
- * @param fn file name
- * @retval *bp buffer (malloc'd) (or NULL)
- * @retval *nbp no. of bytes in buffer (including final NUL) (or NULL)
- * @param flags 1 to trim escaped newlines
- * return 0 on success
- */
-int poptReadFile(const char * fn, /*@null@*/ /*@out@*/ char ** bp,
- /*@null@*/ /*@out@*/ size_t * nbp, int flags)
- /*@globals errno, fileSystem, internalState @*/
- /*@modifies *bp, *nbp, errno, fileSystem, internalState @*/;
-#define POPT_READFILE_TRIMNEWLINES 1
-
-/** \ingroup popt
* Read configuration file.
* @param con context
* @param fn file name to read
* @return 0 on success, POPT_ERROR_ERRNO on failure
*/
int poptReadConfigFile(poptContext con, const char * fn)
- /*@globals errno, fileSystem, internalState @*/
- /*@modifies con->execs, con->numExecs,
- errno, fileSystem, internalState @*/;
-
-/** \ingroup popt
- * Read configuration file(s).
- * Colon separated files to read, looping over poptReadConfigFile().
- * Note that an '@' character preceeding a path in the list will
- * also perform additional sanity checks on the file before reading.
- * @param con context
- * @param paths colon separated file name(s) to read
- * @return 0 on success, POPT_ERROR_BADCONFIG on failure
- */
-int poptReadConfigFiles(poptContext con, /*@null@*/ const char * paths)
- /*@globals errno, fileSystem, internalState @*/
+ /*@globals fileSystem, internalState @*/
/*@modifies con->execs, con->numExecs,
- errno, fileSystem, internalState @*/;
+ fileSystem, internalState @*/;
/** \ingroup popt
* Read default configuration from /etc/popt and $HOME/.popt.
@@ -441,7 +350,6 @@ int poptReadConfigFiles(poptContext con, /*@null@*/ const char * paths)
* @param useEnv (unused)
* @return 0 on success, POPT_ERROR_ERRNO on failure
*/
-/*@unused@*/
int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
/*@globals fileSystem, internalState @*/
/*@modifies con->execs, con->numExecs,
@@ -535,8 +443,7 @@ int poptConfigFileToString(FILE *fp, /*@out@*/ char ** argstrp, int flags)
* @param error popt error
* @return error string
*/
-/*@observer@*/
-const char * poptStrerror(const int error)
+/*@observer@*/ const char* poptStrerror(const int error)
/*@*/;
/** \ingroup popt
@@ -545,29 +452,28 @@ const char * poptStrerror(const int error)
* @param path single path to search for executables
* @param allowAbsolute absolute paths only?
*/
-/*@unused@*/
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute)
/*@modifies con @*/;
/** \ingroup popt
* Print detailed description of options.
* @param con context
- * @param fp ouput file handle
+ * @param fp output file handle
* @param flags (unused)
*/
void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags)
/*@globals fileSystem @*/
- /*@modifies fp, fileSystem @*/;
+ /*@modifies *fp, fileSystem @*/;
/** \ingroup popt
* Print terse description of options.
* @param con context
- * @param fp ouput file handle
+ * @param fp output file handle
* @param flags (unused)
*/
void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags)
/*@globals fileSystem @*/
- /*@modifies fp, fileSystem @*/;
+ /*@modifies *fp, fileSystem @*/;
/** \ingroup popt
* Provide text to replace default "[OPTION...]" in help/usage output.
@@ -585,8 +491,7 @@ void poptSetOtherOptionHelp(poptContext con, const char * text)
* @return argv[0]
*/
/*@-fcnuse@*/
-/*@observer@*/
-const char * poptGetInvocationName(poptContext con)
+/*@observer@*/ const char * poptGetInvocationName(poptContext con)
/*@*/;
/*@=fcnuse@*/
@@ -603,35 +508,6 @@ int poptStrippedArgv(poptContext con, int argc, char ** argv)
/*@=fcnuse@*/
/**
- * Add a string to an argv array.
- * @retval *argvp argv array
- * @param argInfo (unused)
- * @param val string arg to add (using strdup)
- * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
- */
-/*@unused@*/
-int poptSaveString(/*@null@*/ const char *** argvp, unsigned int argInfo,
- /*@null@*/const char * val)
- /*@modifies *argvp @*/;
-
-/**
- * Save a long long, performing logical operation with value.
- * @warning Alignment check may be too strict on certain platorms.
- * @param arg integer pointer, aligned on int boundary.
- * @param argInfo logical operation (see POPT_ARGFLAG_*)
- * @param aLongLong value to use
- * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
- */
-/*@-incondefs@*/
-/*@unused@*/
-int poptSaveLongLong(/*@null@*/ long long * arg, unsigned int argInfo,
- long long aLongLong)
- /*@globals internalState @*/
- /*@modifies *arg, internalState @*/
- /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/;
-/*@=incondefs@*/
-
-/**
* Save a long, performing logical operation with value.
* @warning Alignment check may be too strict on certain platorms.
* @param arg integer pointer, aligned on int boundary.
@@ -641,25 +517,8 @@ int poptSaveLongLong(/*@null@*/ long long * arg, unsigned int argInfo,
*/
/*@-incondefs@*/
/*@unused@*/
-int poptSaveLong(/*@null@*/ long * arg, unsigned int argInfo, long aLong)
- /*@globals internalState @*/
- /*@modifies *arg, internalState @*/
- /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/;
-/*@=incondefs@*/
-
-/**
- * Save a short integer, performing logical operation with value.
- * @warning Alignment check may be too strict on certain platorms.
- * @param arg short pointer, aligned on short boundary.
- * @param argInfo logical operation (see POPT_ARGFLAG_*)
- * @param aLong value to use
- * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
- */
-/*@-incondefs@*/
-/*@unused@*/
-int poptSaveShort(/*@null@*/ short * arg, unsigned int argInfo, long aLong)
- /*@globals internalState @*/
- /*@modifies *arg, internalState @*/
+int poptSaveLong(/*@null@*/ long * arg, int argInfo, long aLong)
+ /*@modifies *arg @*/
/*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/;
/*@=incondefs@*/
@@ -673,70 +532,12 @@ int poptSaveShort(/*@null@*/ short * arg, unsigned int argInfo, long aLong)
*/
/*@-incondefs@*/
/*@unused@*/
-int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong)
- /*@globals internalState @*/
- /*@modifies *arg, internalState @*/
+int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong)
+ /*@modifies *arg @*/
/*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/;
/*@=incondefs@*/
-/* The bit set typedef. */
-/*@-exporttype@*/
-typedef struct poptBits_s {
- unsigned int bits[1];
-} * poptBits;
-/*@=exporttype@*/
-
-#define _POPT_BITS_N 1024U /* estimated population */
-#define _POPT_BITS_M ((3U * _POPT_BITS_N) / 2U)
-#define _POPT_BITS_K 16U /* no. of linear hash combinations */
-
-/*@-exportlocal -exportvar -globuse @*/
-/*@unchecked@*/
-extern unsigned int _poptBitsN;
-/*@unchecked@*/
-extern unsigned int _poptBitsM;
-/*@unchecked@*/
-extern unsigned int _poptBitsK;
-/*@=exportlocal =exportvar =globuse @*/
-
-/*@-exportlocal@*/
-int poptBitsAdd(/*@null@*/poptBits bits, /*@null@*/const char * s)
- /*@modifies bits @*/;
-/*@=exportlocal@*/
-int poptBitsChk(/*@null@*/poptBits bits, /*@null@*/const char * s)
- /*@*/;
-int poptBitsClr(/*@null@*/poptBits bits)
- /*@modifies bits @*/;
-/*@-exportlocal@*/
-int poptBitsDel(/*@null@*/poptBits bits, /*@null@*/const char * s)
- /*@modifies bits @*/;
-/*@-fcnuse@*/
-int poptBitsIntersect(/*@null@*/ poptBits * ap, /*@null@*/ const poptBits b)
- /*@modifies *ap @*/;
-int poptBitsUnion(/*@null@*/ poptBits * ap, /*@null@*/ const poptBits b)
- /*@modifies *ap @*/;
-int poptBitsArgs(/*@null@*/ poptContext con, /*@null@*/ poptBits * ap)
- /*@modifies con, *ap @*/;
-/*@=fcnuse@*/
-/*@=exportlocal@*/
-
-/**
- * Save a string into a bit set (experimental).
- * @retval *bits bit set (lazily malloc'd if NULL)
- * @param argInfo logical operation (see POPT_ARGFLAG_*)
- * @param s string to add to bit set
- * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
- */
-/*@-incondefs@*/
-/*@unused@*/
-int poptSaveBits(/*@null@*/ poptBits * bitsp, unsigned int argInfo,
- /*@null@*/ const char * s)
- /*@globals _poptBitsN, _poptBitsM, _poptBitsK, internalState @*/
- /*@modifies *bitsp, _poptBitsN, _poptBitsM, _poptBitsK, internalState @*/;
-/*@=incondefs@*/
-
/*@=type@*/
-
#ifdef __cplusplus
}
#endif
diff --git a/third_party/popt/poptconfig.c b/third_party/popt/poptconfig.c
index f0a92e0..837828c 100644
--- a/third_party/popt/poptconfig.c
+++ b/third_party/popt/poptconfig.c
@@ -8,346 +8,53 @@
#include "system.h"
#include "poptint.h"
-#include <sys/stat.h>
-
-#if defined(HAVE_FNMATCH_H)
-#include <fnmatch.h>
-
-#if defined(__LCLINT__)
-/*@-declundef -exportheader -incondefs -protoparammatch -redecl -type @*/
-extern int fnmatch (const char *__pattern, const char *__name, int __flags)
- /*@*/;
-/*@=declundef =exportheader =incondefs =protoparammatch =redecl =type @*/
-#endif /* __LCLINT__ */
-#endif
-
-#if defined(HAVE_GLOB_H)
-#include <glob.h>
-
-#if defined(__LCLINT__)
-/*@-declundef -exportheader -incondefs -protoparammatch -redecl -type @*/
-extern int glob (const char *__pattern, int __flags,
- /*@null@*/ int (*__errfunc) (const char *, int),
- /*@out@*/ glob_t *__pglob)
- /*@globals errno, fileSystem @*/
- /*@modifies *__pglob, errno, fileSystem @*/;
-
-/* XXX only annotation is a white lie */
-extern void globfree (/*@only@*/ glob_t *__pglob)
- /*@modifies *__pglob @*/;
-
-/* XXX _GNU_SOURCE ifdef and/or retrofit is needed for portability. */
-extern int glob_pattern_p (const char *__pattern, int __quote)
- /*@*/;
-/*@=declundef =exportheader =incondefs =protoparammatch =redecl =type @*/
-#endif /* __LCLINT__ */
-
-#if !defined(__GLIBC__)
-/* Return nonzero if PATTERN contains any metacharacters.
- Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
-static int
-glob_pattern_p (const char * pattern, int quote)
- /*@*/
-{
- const char * p;
- int open = 0;
-
- for (p = pattern; *p != '\0'; ++p)
- switch (*p) {
- case '?':
- case '*':
- return 1;
- /*@notreached@*/ /*@switchbreak@*/ break;
- case '\\':
- if (quote && p[1] != '\0')
- ++p;
- /*@switchbreak@*/ break;
- case '[':
- open = 1;
- /*@switchbreak@*/ break;
- case ']':
- if (open)
- return 1;
- /*@switchbreak@*/ break;
- }
- return 0;
-}
-#endif /* !defined(__GLIBC__) */
-
-/*@unchecked@*/
-static int poptGlobFlags = 0;
-
-static int poptGlob_error(/*@unused@*/ UNUSED(const char * epath),
- /*@unused@*/ UNUSED(int eerrno))
- /*@*/
-{
- return 1;
-}
-#endif /* HAVE_GLOB_H */
-
-/**
- * Return path(s) from a glob pattern.
- * @param con context
- * @param pattern glob pattern
- * @retval *acp no. of paths
- * @retval *avp array of paths
- * @return 0 on success
- */
-static int poptGlob(/*@unused@*/ UNUSED(poptContext con), const char * pattern,
- /*@out@*/ int * acp, /*@out@*/ const char *** avp)
- /*@modifies *acp, *avp @*/
-{
- const char * pat = pattern;
- int rc = 0; /* assume success */
-
- /* XXX skip the attention marker. */
- if (pat[0] == '@' && pat[1] != '(')
- pat++;
-
-#if defined(HAVE_GLOB_H)
- if (glob_pattern_p(pat, 0)) {
- glob_t _g, *pglob = &_g;
-
- if (!glob(pat, poptGlobFlags, poptGlob_error, pglob)) {
- if (acp) {
- *acp = (int) pglob->gl_pathc;
- pglob->gl_pathc = 0;
- }
- if (avp) {
-/*@-onlytrans@*/
- *avp = (const char **) pglob->gl_pathv;
-/*@=onlytrans@*/
- pglob->gl_pathv = NULL;
- }
-/*@-nullstate@*/
- globfree(pglob);
-/*@=nullstate@*/
- } else
- rc = POPT_ERROR_ERRNO;
- } else
-#endif /* HAVE_GLOB_H */
- {
- if (acp)
- *acp = 1;
- if (avp && (*avp = calloc((size_t)(1 + 1), sizeof (**avp))) != NULL)
- (*avp)[0] = xstrdup(pat);
- }
-
- return rc;
-}
-
-/*@access poptContext @*/
-
-int poptSaneFile(const char * fn)
-{
- struct stat sb;
- uid_t uid = getuid();
-
- if (stat(fn, &sb) == -1)
- return 1;
- if ((uid_t)sb.st_uid != uid)
- return 0;
- if (!S_ISREG(sb.st_mode))
- return 0;
-/*@-bitwisesigned@*/
- if (sb.st_mode & (S_IWGRP|S_IWOTH))
- return 0;
-/*@=bitwisesigned@*/
- return 1;
-}
-
-int poptReadFile(const char * fn, char ** bp, size_t * nbp, int flags)
-{
- int fdno;
- char * b = NULL;
- off_t nb = 0;
- char * s, * t, * se;
- int rc = POPT_ERROR_ERRNO; /* assume failure */
-
- fdno = open(fn, O_RDONLY);
- if (fdno < 0)
- goto exit;
-
- if ((nb = lseek(fdno, 0, SEEK_END)) == (off_t)-1
- || lseek(fdno, 0, SEEK_SET) == (off_t)-1
- || (b = calloc(sizeof(*b), (size_t)nb + 1)) == NULL
- || read(fdno, (char *)b, (size_t)nb) != (ssize_t)nb)
- {
- int oerrno = errno;
- (void) close(fdno);
- errno = oerrno;
- goto exit;
- }
- if (close(fdno) == -1)
- goto exit;
- if (b == NULL) {
- rc = POPT_ERROR_MALLOC;
- goto exit;
- }
- rc = 0;
-
- /* Trim out escaped newlines. */
-/*@-bitwisesigned@*/
- if (flags & POPT_READFILE_TRIMNEWLINES)
-/*@=bitwisesigned@*/
- {
- for (t = b, s = b, se = b + nb; *s && s < se; s++) {
- switch (*s) {
- case '\\':
- if (s[1] == '\n') {
- s++;
- continue;
- }
- /*@fallthrough@*/
- default:
- *t++ = *s;
- /*@switchbreak@*/ break;
- }
- }
- *t++ = '\0';
- nb = (off_t)(t - b);
- }
-
-exit:
- if (rc != 0) {
-/*@-usedef@*/
- if (b)
- free(b);
-/*@=usedef@*/
- b = NULL;
- nb = 0;
- }
- if (bp)
- *bp = b;
-/*@-usereleased@*/
- else if (b)
- free(b);
-/*@=usereleased@*/
- if (nbp)
- *nbp = (size_t)nb;
-/*@-compdef -nullstate @*/ /* XXX cannot annotate char ** correctly */
- return rc;
-/*@=compdef =nullstate @*/
-}
-
-/**
- * Check for application match.
- * @param con context
- * @param s config application name
- * return 0 if config application matches
- */
-static int configAppMatch(poptContext con, const char * s)
- /*@*/
-{
- int rc = 1;
-
- if (con->appName == NULL) /* XXX can't happen. */
- return rc;
-
-#if defined(HAVE_GLOB_H) && defined(HAVE_FNMATCH_H)
- if (glob_pattern_p(s, 1)) {
-/*@-bitwisesigned@*/
- static int flags = FNM_PATHNAME | FNM_PERIOD;
-#ifdef FNM_EXTMATCH
- flags |= FNM_EXTMATCH;
-#endif
-/*@=bitwisesigned@*/
- rc = fnmatch(s, con->appName, flags);
- } else
-#endif
- rc = strcmp(s, con->appName);
- return rc;
-}
/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */
-static int poptConfigLine(poptContext con, char * line)
- /*@globals fileSystem, internalState @*/
- /*@modifies con, fileSystem, internalState @*/
+static void configLine(poptContext con, char * line)
+ /*@modifies con @*/
{
- char *b = NULL;
- size_t nb = 0;
- char * se = line;
- const char * appName;
+ /*@-type@*/
+ int nameLength = strlen(con->appName);
+ /*@=type@*/
const char * entryType;
const char * opt;
- struct poptItem_s item_buf;
- poptItem item = &item_buf;
+ poptItem item = (poptItem)alloca(sizeof(*item));
int i, j;
- int rc = POPT_ERROR_BADCONFIG;
-
- if (con->appName == NULL)
- goto exit;
+/*@-boundswrite@*/
memset(item, 0, sizeof(*item));
- appName = se;
- while (*se != '\0' && !_isspaceptr(se)) se++;
- if (*se == '\0')
- goto exit;
- else
- *se++ = '\0';
+ /*@-type@*/
+ if (strncmp(line, con->appName, nameLength)) return;
+ /*@=type@*/
- if (configAppMatch(con, appName)) goto exit;
+ line += nameLength;
+ if (*line == '\0' || !isspace(*line)) return;
- while (*se != '\0' && _isspaceptr(se)) se++;
- entryType = se;
- while (*se != '\0' && !_isspaceptr(se)) se++;
- if (*se != '\0') *se++ = '\0';
+ while (*line != '\0' && isspace(*line)) line++;
+ entryType = line;
+ while (*line == '\0' || !isspace(*line)) line++;
+ *line++ = '\0';
- while (*se != '\0' && _isspaceptr(se)) se++;
- if (*se == '\0') goto exit;
- opt = se;
- while (*se != '\0' && !_isspaceptr(se)) se++;
- if (opt[0] == '-' && *se == '\0') goto exit;
- if (*se != '\0') *se++ = '\0';
+ while (*line != '\0' && isspace(*line)) line++;
+ if (*line == '\0') return;
+ opt = line;
+ while (*line == '\0' || !isspace(*line)) line++;
+ *line++ = '\0';
- while (*se != '\0' && _isspaceptr(se)) se++;
- if (opt[0] == '-' && *se == '\0') goto exit;
+ while (*line != '\0' && isspace(*line)) line++;
+ if (*line == '\0') return;
-/*@-temptrans@*/ /* FIX: line alias is saved */
+ /*@-temptrans@*/ /* FIX: line alias is saved */
if (opt[0] == '-' && opt[1] == '-')
item->option.longName = opt + 2;
else if (opt[0] == '-' && opt[2] == '\0')
item->option.shortName = opt[1];
- else {
- const char * fn = opt;
+ /*@=temptrans@*/
- /* XXX handle globs and directories in fn? */
- if ((rc = poptReadFile(fn, &b, &nb, POPT_READFILE_TRIMNEWLINES)) != 0)
- goto exit;
- if (b == NULL || nb == 0)
- goto exit;
+ if (poptParseArgvString(line, &item->argc, &item->argv)) return;
- /* Append remaining text to the interpolated file option text. */
- if (*se != '\0') {
- size_t nse = strlen(se) + 1;
- if ((b = realloc(b, (nb + nse))) == NULL) /* XXX can't happen */
- goto exit;
- (void) stpcpy( stpcpy(&b[nb-1], " "), se);
- nb += nse;
- }
- se = b;
-
- /* Use the basename of the path as the long option name. */
- { const char * longName = strrchr(fn, '/');
- if (longName != NULL)
- longName++;
- else
- longName = fn;
- if (longName == NULL) /* XXX can't happen. */
- goto exit;
- /* Single character basenames are treated as short options. */
- if (longName[1] != '\0')
- item->option.longName = longName;
- else
- item->option.shortName = longName[0];
- }
- }
-/*@=temptrans@*/
-
- if (poptParseArgvString(se, &item->argc, &item->argv)) goto exit;
-
-/*@-modobserver@*/
+ /*@-modobserver@*/
item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
for (i = 0, j = 0; i < item->argc; i++, j++) {
const char * f;
@@ -373,210 +80,111 @@ static int poptConfigLine(poptContext con, char * line)
item->argv[j] = NULL;
item->argc = j;
}
-/*@=modobserver@*/
+ /*@=modobserver@*/
+/*@=boundswrite@*/
-/*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
+ /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
if (!strcmp(entryType, "alias"))
- rc = poptAddItem(con, item, 0);
+ (void) poptAddItem(con, item, 0);
else if (!strcmp(entryType, "exec"))
- rc = poptAddItem(con, item, 1);
-/*@=nullstate@*/
-exit:
- rc = 0; /* XXX for now, always return success */
- if (b)
- free(b);
- return rc;
+ (void) poptAddItem(con, item, 1);
+ /*@=nullstate@*/
}
/*@=compmempass@*/
int poptReadConfigFile(poptContext con, const char * fn)
{
- char * b = NULL, *be;
- size_t nb = 0;
- const char *se;
- char *t, *te;
- int rc;
- int xx;
+ const char * file, * chptr, * end;
+ char * buf;
+/*@dependent@*/ char * dst;
+ int fd, rc;
+ off_t fileLength;
+
+ fd = open(fn, O_RDONLY);
+ if (fd < 0)
+ return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
+
+ fileLength = lseek(fd, 0, SEEK_END);
+ if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
+ rc = errno;
+ (void) close(fd);
+ /*@-mods@*/
+ errno = rc;
+ /*@=mods@*/
+ return POPT_ERROR_ERRNO;
+ }
- if ((rc = poptReadFile(fn, &b, &nb, POPT_READFILE_TRIMNEWLINES)) != 0)
- return (errno == ENOENT ? 0 : rc);
- if (b == NULL || nb == 0)
- return POPT_ERROR_BADCONFIG;
+ file = (const char *)alloca(fileLength + 1);
+ if (read(fd, (char *)file, fileLength) != fileLength) {
+ rc = errno;
+ (void) close(fd);
+ /*@-mods@*/
+ errno = rc;
+ /*@=mods@*/
+ return POPT_ERROR_ERRNO;
+ }
+ if (close(fd) == -1)
+ return POPT_ERROR_ERRNO;
- if ((t = malloc(nb + 1)) == NULL)
- goto exit;
- te = t;
+/*@-boundswrite@*/
+ dst = buf = (char *)alloca(fileLength + 1);
- be = (b + nb);
- for (se = b; se < be; se++) {
- switch (*se) {
+ chptr = file;
+ end = (file + fileLength);
+ /*@-infloops@*/ /* LCL: can't detect chptr++ */
+ while (chptr < end) {
+ switch (*chptr) {
case '\n':
- *te = '\0';
- te = t;
- while (*te && _isspaceptr(te)) te++;
- if (*te && *te != '#')
- xx = poptConfigLine(con, te);
+ *dst = '\0';
+ dst = buf;
+ while (*dst && isspace(*dst)) dst++;
+ if (*dst && *dst != '#')
+ configLine(con, dst);
+ chptr++;
/*@switchbreak@*/ break;
-/*@-usedef@*/ /* XXX *se may be uninitialized */
case '\\':
- *te = *se++;
- /* \ at the end of a line does not insert a \n */
- if (se < be && *se != '\n') {
- te++;
- *te++ = *se;
+ *dst++ = *chptr++;
+ if (chptr < end) {
+ if (*chptr == '\n')
+ dst--, chptr++;
+ /* \ at the end of a line does not insert a \n */
+ else
+ *dst++ = *chptr++;
}
/*@switchbreak@*/ break;
default:
- *te++ = *se;
+ *dst++ = *chptr++;
/*@switchbreak@*/ break;
-/*@=usedef@*/
}
}
+ /*@=infloops@*/
+/*@=boundswrite@*/
- free(t);
- rc = 0;
-
-exit:
- if (b)
- free(b);
- return rc;
-}
-
-int poptReadConfigFiles(poptContext con, const char * paths)
-{
- char * buf = (paths ? xstrdup(paths) : NULL);
- const char * p;
- char * pe;
- int rc = 0; /* assume success */
-
- for (p = buf; p != NULL && *p != '\0'; p = pe) {
- const char ** av = NULL;
- int ac = 0;
- int i;
- int xx;
-
- /* locate start of next path element */
- pe = strchr(p, ':');
- if (pe != NULL && *pe == ':')
- *pe++ = '\0';
- else
- pe = (char *) (p + strlen(p));
-
- xx = poptGlob(con, p, &ac, &av);
-
- /* work-off each resulting file from the path element */
- for (i = 0; i < ac; i++) {
- const char * fn = av[i];
- if (av[i] == NULL) /* XXX can't happen */
- /*@innercontinue@*/ continue;
- /* XXX should '@' attention be pushed into poptReadConfigFile? */
- if (p[0] == '@' && p[1] != '(') {
- if (fn[0] == '@' && fn[1] != '(')
- fn++;
- xx = poptSaneFile(fn);
- if (!xx && rc == 0)
- rc = POPT_ERROR_BADCONFIG;
- /*@innercontinue@*/ continue;
- }
- xx = poptReadConfigFile(con, fn);
- if (xx && rc == 0)
- rc = xx;
- free((void *)av[i]);
- av[i] = NULL;
- }
- free(av);
- av = NULL;
- }
-
-/*@-usedef@*/
- if (buf)
- free(buf);
-/*@=usedef@*/
-
- return rc;
+ return 0;
}
-int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv))
+int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
{
- static const char _popt_sysconfdir[] = POPT_SYSCONFDIR "/popt";
- static const char _popt_etc[] = "/etc/popt";
- char * home;
- struct stat sb;
- int rc = 0; /* assume success */
-
- if (con->appName == NULL) goto exit;
-
- if (strcmp(_popt_sysconfdir, _popt_etc)) {
- rc = poptReadConfigFile(con, _popt_sysconfdir);
- if (rc) goto exit;
- }
-
- rc = poptReadConfigFile(con, _popt_etc);
- if (rc) goto exit;
+ char * fn, * home;
+ int rc;
-#if defined(HAVE_GLOB_H)
- if (!stat("/etc/popt.d", &sb) && S_ISDIR(sb.st_mode)) {
- const char ** av = NULL;
- int ac = 0;
- int i;
+ /*@-type@*/
+ if (!con->appName) return 0;
+ /*@=type@*/
- if ((rc = poptGlob(con, "/etc/popt.d/*", &ac, &av)) == 0) {
- for (i = 0; rc == 0 && i < ac; i++) {
- const char * fn = av[i];
- if (fn == NULL || strstr(fn, ".rpmnew") || strstr(fn, ".rpmsave"))
- continue;
- if (!stat(fn, &sb)) {
- if (!S_ISREG(sb.st_mode) && !S_ISLNK(sb.st_mode))
- continue;
- }
- rc = poptReadConfigFile(con, fn);
- free((void *)av[i]);
- av[i] = NULL;
- }
- free(av);
- av = NULL;
- }
- }
- if (rc) goto exit;
+ rc = poptReadConfigFile(con, "/etc/popt");
+ if (rc) return rc;
+#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
+ if (getuid() != geteuid()) return 0;
#endif
if ((home = getenv("HOME"))) {
- char * fn = malloc(strlen(home) + 20);
- if (fn != NULL) {
- (void) stpcpy(stpcpy(fn, home), "/.popt");
- rc = poptReadConfigFile(con, fn);
- free(fn);
- } else
- rc = POPT_ERROR_ERRNO;
- if (rc) goto exit;
+ fn = (char *)alloca(strlen(home) + 20);
+ strcpy(fn, home);
+ strcat(fn, "/.popt");
+ rc = poptReadConfigFile(con, fn);
+ if (rc) return rc;
}
-exit:
- return rc;
-}
-
-poptContext
-poptFini(poptContext con)
-{
- return poptFreeContext(con);
-}
-
-poptContext
-poptInit(int argc, const char ** argv,
- const struct poptOption * options, const char * configPaths)
-{
- poptContext con = NULL;
- const char * argv0;
-
- if (argv == NULL || argv[0] == NULL || options == NULL)
- return con;
-
- if ((argv0 = strrchr(argv[0], '/')) != NULL) argv0++;
- else argv0 = argv[0];
-
- con = poptGetContext(argv0, argc, (const char **)argv, options, 0);
- if (con != NULL&& poptReadConfigFiles(con, configPaths))
- con = poptFini(con);
-
- return con;
+ return 0;
}
diff --git a/third_party/popt/popthelp.c b/third_party/popt/popthelp.c
index 0d8548b..4e2a1a5 100644
--- a/third_party/popt/popthelp.c
+++ b/third_party/popt/popthelp.c
@@ -1,5 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*@-type@*/
/** \ingroup popt
* \file popt/popthelp.c
*/
@@ -9,21 +10,8 @@
ftp://ftp.rpm.org/pub/rpm/dist. */
#include "system.h"
-
-#define POPT_USE_TIOCGWINSZ
-#ifdef POPT_USE_TIOCGWINSZ
-#include <sys/ioctl.h>
-#endif
-
-#define POPT_WCHAR_HACK
-#ifdef POPT_WCHAR_HACK
-#include <wchar.h> /* for mbsrtowcs */
-/*@access mbstate_t @*/
-#endif
#include "poptint.h"
-/*@access poptContext@*/
-
/**
* Display arguments.
* @param con context
@@ -32,12 +20,10 @@
* @param arg (unused)
* @param data (unused)
*/
-/*@exits@*/
static void displayArgs(poptContext con,
- /*@unused@*/ UNUSED(enum poptCallbackReason foo),
+ /*@unused@*/ enum poptCallbackReason foo,
struct poptOption * key,
- /*@unused@*/ UNUSED(const char * arg),
- /*@unused@*/ UNUSED(void * data))
+ /*@unused@*/ const char * arg, /*@unused@*/ void * data)
/*@globals fileSystem@*/
/*@modifies fileSystem@*/
{
@@ -45,10 +31,6 @@ static void displayArgs(poptContext con,
poptPrintHelp(con, stdout, 0);
else
poptPrintUsage(con, stdout, 0);
-
-#if !defined(__LCLINT__) /* XXX keep both splint & valgrind happy */
- con = poptFreeContext(con);
-#endif
exit(0);
}
@@ -71,97 +53,30 @@ struct poptOption poptAliasOptions[] = {
/*@-castfcnptr@*/
/*@observer@*/ /*@unchecked@*/
struct poptOption poptHelpOptions[] = {
- { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL },
- { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL },
- { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL },
- POPT_TABLEEND
-} ;
-
-/*@observer@*/ /*@unchecked@*/
-static struct poptOption poptHelpOptions2[] = {
-/*@-readonlytrans@*/
- { NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL},
-/*@=readonlytrans@*/
- { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL },
- { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL },
- { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL },
+ { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
+ { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
+ { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
#ifdef NOTYET
{ "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0,
N_("Display option defaults in message"), NULL },
#endif
- { "", '\0', 0, NULL, 0, N_("Terminate options"), NULL },
POPT_TABLEEND
} ;
-
-/*@observer@*/ /*@unchecked@*/
-struct poptOption * poptHelpOptionsI18N = poptHelpOptions2;
/*@=castfcnptr@*/
-#define _POPTHELP_MAXLINE ((size_t)79)
-
-typedef struct columns_s {
- size_t cur;
- size_t max;
-} * columns_t;
-
-/**
- * Return no. of columns in output window.
- * @param fp FILE
- * @return no. of columns
- */
-static size_t maxColumnWidth(FILE *fp)
- /*@*/
-{
- size_t maxcols = _POPTHELP_MAXLINE;
-#if defined(TIOCGWINSZ)
- struct winsize ws;
- int fdno = fileno(fp ? fp : stdout);
-
- memset(&ws, 0, sizeof(ws));
- if (fdno >= 0 && !ioctl(fdno, (unsigned long)TIOCGWINSZ, &ws)) {
- size_t ws_col = (size_t)ws.ws_col;
- if (ws_col > maxcols && ws_col < (size_t)256)
- maxcols = ws_col - 1;
- }
-#endif
- return maxcols;
-}
-
-/**
- * Determine number of display characters in a string.
- * @param s string
- * @return no. of display characters.
- */
-static inline size_t stringDisplayWidth(const char *s)
- /*@*/
-{
- size_t n = strlen(s);
-#ifdef POPT_WCHAR_HACK
- mbstate_t t;
-
- memset ((void *)&t, 0, sizeof (t)); /* In initial state. */
- /* Determine number of display characters. */
- n = mbsrtowcs (NULL, &s, n, &t);
-#else
- n = 0;
- for (; *s; s = POPT_next_char(s))
- n++;
-#endif
-
- return n;
-}
-
/**
- * @param opt option(s)
+ * @param table option(s)
*/
/*@observer@*/ /*@null@*/ static const char *
-getTableTranslationDomain(/*@null@*/ const struct poptOption *opt)
+getTableTranslationDomain(/*@null@*/ const struct poptOption *table)
/*@*/
{
- if (opt != NULL)
- for (; opt->longName || opt->shortName || opt->arg; opt++) {
+ const struct poptOption *opt;
+
+ if (table != NULL)
+ for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
if (opt->argInfo == POPT_ARG_INTL_DOMAIN)
- return opt->arg;
+ return (char *)opt->arg;
}
return NULL;
}
@@ -177,26 +92,14 @@ getArgDescrip(const struct poptOption * opt,
/*@=paramuse@*/
/*@*/
{
- if (!poptArgType(opt)) return NULL;
-
- if (poptArgType(opt) == POPT_ARG_MAINCALL)
- return opt->argDescrip;
- if (poptArgType(opt) == POPT_ARG_ARGV)
- return opt->argDescrip;
-
- if (opt->argDescrip) {
- /* Some strings need popt library, not application, i18n domain. */
- if (opt == (poptHelpOptions + 1)
- || opt == (poptHelpOptions + 2)
- || !strcmp(opt->argDescrip, N_("Help options:"))
- || !strcmp(opt->argDescrip, N_("Options implemented via popt alias/exec:")))
- return POPT_(opt->argDescrip);
-
- /* Use the application i18n domain. */
- return D_(translation_domain, opt->argDescrip);
- }
+ if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
- switch (poptArgType(opt)) {
+ if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2))
+ if (opt->argDescrip) return POPT_(opt->argDescrip);
+
+ if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
+
+ switch (opt->argInfo & POPT_ARG_MASK) {
case POPT_ARG_NONE: return POPT_("NONE");
#ifdef DYING
case POPT_ARG_VAL: return POPT_("VAL");
@@ -204,27 +107,23 @@ getArgDescrip(const struct poptOption * opt,
case POPT_ARG_VAL: return NULL;
#endif
case POPT_ARG_INT: return POPT_("INT");
- case POPT_ARG_SHORT: return POPT_("SHORT");
case POPT_ARG_LONG: return POPT_("LONG");
- case POPT_ARG_LONGLONG: return POPT_("LONGLONG");
case POPT_ARG_STRING: return POPT_("STRING");
case POPT_ARG_FLOAT: return POPT_("FLOAT");
case POPT_ARG_DOUBLE: return POPT_("DOUBLE");
- case POPT_ARG_MAINCALL: return NULL;
- case POPT_ARG_ARGV: return NULL;
default: return POPT_("ARG");
}
}
/**
* Display default value for an option.
- * @param lineLength display positions remaining
+ * @param lineLength
* @param opt option(s)
* @param translation_domain translation domain
* @return
*/
static /*@only@*/ /*@null@*/ char *
-singleOptionDefaultValue(size_t lineLength,
+singleOptionDefaultValue(int lineLength,
const struct poptOption * opt,
/*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */
/*@null@*/ const char * translation_domain)
@@ -232,67 +131,58 @@ singleOptionDefaultValue(size_t lineLength,
/*@*/
{
const char * defstr = D_(translation_domain, "default");
- char * le = malloc(4*lineLength + 1);
+ char * le = (char *)malloc(4*lineLength + 1);
char * l = le;
if (le == NULL) return NULL; /* XXX can't happen */
+/*@-boundswrite@*/
*le = '\0';
*le++ = '(';
- le = stpcpy(le, defstr);
+ strcpy(le, defstr); le += strlen(le);
*le++ = ':';
*le++ = ' ';
- if (opt->arg) { /* XXX programmer error */
- poptArg arg = { .ptr = opt->arg };
- switch (poptArgType(opt)) {
+ if (opt->arg) /* XXX programmer error */
+ switch (opt->argInfo & POPT_ARG_MASK) {
case POPT_ARG_VAL:
case POPT_ARG_INT:
- le += sprintf(le, "%d", arg.intp[0]);
- break;
- case POPT_ARG_SHORT:
- le += sprintf(le, "%hd", arg.shortp[0]);
- break;
+ { long aLong = *((int *)opt->arg);
+ le += sprintf(le, "%ld", aLong);
+ } break;
case POPT_ARG_LONG:
- le += sprintf(le, "%ld", arg.longp[0]);
- break;
- case POPT_ARG_LONGLONG:
- le += sprintf(le, "%lld", arg.longlongp[0]);
- break;
+ { long aLong = *((long *)opt->arg);
+ le += sprintf(le, "%ld", aLong);
+ } break;
case POPT_ARG_FLOAT:
- { double aDouble = (double) arg.floatp[0];
+ { double aDouble = *((float *)opt->arg);
le += sprintf(le, "%g", aDouble);
} break;
case POPT_ARG_DOUBLE:
- le += sprintf(le, "%g", arg.doublep[0]);
- break;
- case POPT_ARG_MAINCALL:
- le += sprintf(le, "%p", opt->arg);
- break;
- case POPT_ARG_ARGV:
- le += sprintf(le, "%p", opt->arg);
- break;
+ { double aDouble = *((double *)opt->arg);
+ le += sprintf(le, "%g", aDouble);
+ } break;
case POPT_ARG_STRING:
- { const char * s = arg.argv[0];
- if (s == NULL)
- le = stpcpy(le, "null");
- else {
- size_t limit = 4*lineLength - (le - l) - sizeof("\"\")");
- size_t slen;
+ { const char * s = *(const char **)opt->arg;
+ if (s == NULL) {
+ strcpy(le, "null"); le += strlen(le);
+ } else {
+ size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")");
*le++ = '"';
- strncpy(le, s, limit); le[limit] = '\0'; le += (slen = strlen(le));
- if (slen == limit && s[limit])
- le[-1] = le[-2] = le[-3] = '.';
+ strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le);
+ if (slen < strlen(s)) {
+ strcpy(le, "..."); le += strlen(le);
+ }
*le++ = '"';
}
} break;
case POPT_ARG_NONE:
default:
- l = _free(l);
+ l = (char *)_free(l);
return NULL;
/*@notreached@*/ break;
}
- }
*le++ = ')';
*le = '\0';
+/*@=boundswrite@*/
return l;
}
@@ -300,104 +190,85 @@ singleOptionDefaultValue(size_t lineLength,
/**
* Display help text for an option.
* @param fp output file handle
- * @param columns output display width control
+ * @param maxLeftCol
* @param opt option(s)
* @param translation_domain translation domain
*/
-static void singleOptionHelp(FILE * fp, columns_t columns,
+static void singleOptionHelp(FILE * fp, int maxLeftCol,
const struct poptOption * opt,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
- /*@modifies fp, fileSystem @*/
+ /*@modifies *fp, fileSystem @*/
{
- size_t maxLeftCol = columns->cur;
- size_t indentLength = maxLeftCol + 5;
- size_t lineLength = columns->max - indentLength;
+ int indentLength = maxLeftCol + 5;
+ int lineLength = 79 - indentLength;
const char * help = D_(translation_domain, opt->descrip);
const char * argDescrip = getArgDescrip(opt, translation_domain);
- /* Display shortName iff printable non-space. */
- int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' ');
- size_t helpLength;
+ int helpLength;
char * defs = NULL;
char * left;
- size_t nb = maxLeftCol + 1;
- int displaypad = 0;
- int xx;
+ int nb = maxLeftCol + 1;
/* Make sure there's more than enough room in target buffer. */
if (opt->longName) nb += strlen(opt->longName);
- if (F_ISSET(opt, TOGGLE)) nb += sizeof("[no]") - 1;
if (argDescrip) nb += strlen(argDescrip);
- left = malloc(nb);
+/*@-boundswrite@*/
+ left = (char *)malloc(nb);
if (left == NULL) return; /* XXX can't happen */
left[0] = '\0';
left[maxLeftCol] = '\0';
-#define prtlong (opt->longName != NULL) /* XXX splint needs a clue */
- if (!(prtshort || prtlong))
- goto out;
- if (prtshort && prtlong) {
- char *dash = F_ISSET(opt, ONEDASH) ? "-" : "--";
- left[0] = '-';
- left[1] = opt->shortName;
- (void) stpcpy(stpcpy(stpcpy(left+2, ", "), dash), opt->longName);
- } else if (prtshort) {
- left[0] = '-';
- left[1] = opt->shortName;
- left[2] = '\0';
- } else if (prtlong) {
- /* XXX --long always padded for alignment with/without "-X, ". */
- char *dash = poptArgType(opt) == POPT_ARG_MAINCALL ? ""
- : (F_ISSET(opt, ONEDASH) ? "-" : "--");
- const char *longName = opt->longName;
- const char *toggle;
- if (F_ISSET(opt, TOGGLE)) {
- toggle = "[no]";
- if (longName[0] == 'n' && longName[1] == 'o') {
- longName += sizeof("no") - 1;
- if (longName[0] == '-')
- longName++;
- }
- } else
- toggle = "";
- (void) stpcpy(stpcpy(stpcpy(stpcpy(left, " "), dash), toggle), longName);
- }
-#undef prtlong
+ if (opt->longName && opt->shortName)
+ sprintf(left, "-%c, %s%s", opt->shortName,
+ ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
+ opt->longName);
+ else if (opt->shortName != '\0')
+ sprintf(left, "-%c", opt->shortName);
+ else if (opt->longName)
+ sprintf(left, "%s%s",
+ ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
+ opt->longName);
+ if (!*left) goto out;
if (argDescrip) {
char * le = left + strlen(left);
- if (F_ISSET(opt, OPTIONAL))
+ if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
*le++ = '[';
/* Choose type of output */
- if (F_ISSET(opt, SHOW_DEFAULT)) {
- defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
- if (defs) {
- char * t = malloc((help ? strlen(help) : 0) +
+ /*@-branchstate@*/
+ if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) {
+ defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
+ if (defs) {
+ char * t = (char *)malloc((help ? strlen(help) : 0) +
strlen(defs) + sizeof(" "));
- if (t) {
- char * te = t;
- if (help)
- te = stpcpy(te, help);
- *te++ = ' ';
- strcpy(te, defs);
- defs = _free(defs);
- defs = t;
+ if (t) {
+ char * te = t;
+ *te = '\0';
+ if (help) {
+ strcpy(te, help);
+ te += strlen(te);
+ }
+ *te++ = ' ';
+ strcpy(te, defs);
+ }
+ defs = (char *)_free(defs);
+ defs = t;
}
- }
}
+ /*@=branchstate@*/
if (opt->argDescrip == NULL) {
- switch (poptArgType(opt)) {
+ switch (opt->argInfo & POPT_ARG_MASK) {
case POPT_ARG_NONE:
break;
case POPT_ARG_VAL:
#ifdef NOTNOW /* XXX pug ugly nerdy output */
{ long aLong = opt->val;
- int ops = F_ISSET(opt, LOGICALOPS);
- int negate = F_ISSET(opt, NOT);
+ int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS);
+ int negate = (opt->argInfo & POPT_ARGFLAG_NOT);
/* Don't bother displaying typical values */
if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L))
@@ -416,7 +287,7 @@ static void singleOptionHelp(FILE * fp, columns_t columns,
default:
/*@innerbreak@*/ break;
}
- *le++ = (opt->longName != NULL ? '=' : ' ');
+ *le++ = '=';
if (negate) *le++ = '~';
/*@-formatconst@*/
le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong);
@@ -426,133 +297,104 @@ static void singleOptionHelp(FILE * fp, columns_t columns,
#endif
break;
case POPT_ARG_INT:
- case POPT_ARG_SHORT:
case POPT_ARG_LONG:
- case POPT_ARG_LONGLONG:
case POPT_ARG_FLOAT:
case POPT_ARG_DOUBLE:
case POPT_ARG_STRING:
- *le++ = (opt->longName != NULL ? '=' : ' ');
- le = stpcpy(le, argDescrip);
+ *le++ = '=';
+ strcpy(le, argDescrip); le += strlen(le);
break;
default:
break;
}
} else {
- char *leo;
-
- /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */
- if (!strchr(" =(", argDescrip[0]))
- *le++ = ((poptArgType(opt) == POPT_ARG_MAINCALL) ? ' ' :
- (poptArgType(opt) == POPT_ARG_ARGV) ? ' ' : '=');
- le = stpcpy(leo = le, argDescrip);
-
- /* Adjust for (possible) wide characters. */
- displaypad = (int)((le - leo) - stringDisplayWidth(argDescrip));
+ *le++ = '=';
+ strcpy(le, argDescrip); le += strlen(le);
}
- if (F_ISSET(opt, OPTIONAL))
+ if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
*le++ = ']';
*le = '\0';
}
+/*@=boundswrite@*/
if (help)
- xx = POPT_fprintf(fp," %-*s ", (int)(maxLeftCol+displaypad), left);
+ fprintf(fp," %-*s ", maxLeftCol, left);
else {
- xx = POPT_fprintf(fp," %s\n", left);
+ fprintf(fp," %s\n", left);
goto out;
}
- left = _free(left);
- if (defs)
+ left = (char *)_free(left);
+ if (defs) {
help = defs;
+ }
helpLength = strlen(help);
+/*@-boundsread@*/
while (helpLength > lineLength) {
const char * ch;
char format[16];
ch = help + lineLength - 1;
- while (ch > help && !_isspaceptr(ch))
- ch = POPT_prev_char(ch);
+ while (ch > help && !isspace(*ch)) ch--;
if (ch == help) break; /* give up */
- while (ch > (help + 1) && _isspaceptr(ch))
- ch = POPT_prev_char (ch);
- ch = POPT_next_char(ch);
-
- /*
- * XXX strdup is necessary to add NUL terminator so that an unknown
- * no. of (possible) multi-byte characters can be displayed.
- */
- { char * fmthelp = xstrdup(help);
- if (fmthelp) {
- fmthelp[ch - help] = '\0';
- sprintf(format, "%%s\n%%%ds", (int) indentLength);
- /*@-formatconst@*/
- xx = POPT_fprintf(fp, format, fmthelp, " ");
- /*@=formatconst@*/
- free(fmthelp);
- }
- }
+ while (ch > (help + 1) && isspace(*ch)) ch--;
+ ch++;
+ sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
+ /*@-formatconst@*/
+ fprintf(fp, format, help, " ");
+ /*@=formatconst@*/
help = ch;
- while (_isspaceptr(help) && *help)
- help = POPT_next_char(help);
+ while (isspace(*help) && *help) help++;
helpLength = strlen(help);
}
+/*@=boundsread@*/
if (helpLength) fprintf(fp, "%s\n", help);
- help = NULL;
out:
/*@-dependenttrans@*/
- defs = _free(defs);
+ defs = (char *)_free(defs);
/*@=dependenttrans@*/
- left = _free(left);
+ left = (char *)_free(left);
}
/**
- * Find display width for longest argument string.
* @param opt option(s)
* @param translation_domain translation domain
- * @return display width
*/
-static size_t maxArgWidth(const struct poptOption * opt,
+static int maxArgWidth(const struct poptOption * opt,
/*@null@*/ const char * translation_domain)
/*@*/
{
- size_t max = 0;
- size_t len = 0;
- const char * argDescrip;
+ int max = 0;
+ int len = 0;
+ const char * s;
if (opt != NULL)
while (opt->longName || opt->shortName || opt->arg) {
- if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) {
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
if (opt->arg) /* XXX program error */
- len = maxArgWidth(opt->arg, translation_domain);
+ len = maxArgWidth((const struct poptOption *)opt->arg, translation_domain);
if (len > max) max = len;
- } else if (!F_ISSET(opt, DOC_HIDDEN)) {
+ } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
len = sizeof(" ")-1;
- /* XXX --long always padded for alignment with/without "-X, ". */
- len += sizeof("-X, ")-1;
+ if (opt->shortName != '\0') len += sizeof("-X")-1;
+ if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1;
if (opt->longName) {
- len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1;
+ len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH)
+ ? sizeof("-")-1 : sizeof("--")-1);
len += strlen(opt->longName);
}
- argDescrip = getArgDescrip(opt, translation_domain);
-
- if (argDescrip) {
-
- /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */
- if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1;
-
- /* Adjust for (possible) wide characters. */
- len += stringDisplayWidth(argDescrip);
- }
-
- if (F_ISSET(opt, OPTIONAL)) len += sizeof("[]")-1;
+ s = getArgDescrip(opt, translation_domain);
+ if (s)
+ len += sizeof("=")-1 + strlen(s);
+ if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1;
if (len > max) max = len;
}
+
opt++;
}
@@ -564,15 +406,14 @@ static size_t maxArgWidth(const struct poptOption * opt,
* @param fp output file handle
* @param items alias/exec array
* @param nitems no. of alias/exec entries
- * @param columns output display width control
+ * @param left
* @param translation_domain translation domain
*/
static void itemHelp(FILE * fp,
- /*@null@*/ poptItem items, int nitems,
- columns_t columns,
+ /*@null@*/ poptItem items, int nitems, int left,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
- /*@modifies fp, fileSystem @*/
+ /*@modifies *fp, fileSystem @*/
{
poptItem item;
int i;
@@ -581,8 +422,9 @@ static void itemHelp(FILE * fp,
for (i = 0, item = items; i < nitems; i++, item++) {
const struct poptOption * opt;
opt = &item->option;
- if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN))
- singleOptionHelp(fp, columns, opt, translation_domain);
+ if ((opt->longName || opt->shortName) &&
+ !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
+ singleOptionHelp(fp, left, opt, translation_domain);
}
}
@@ -591,47 +433,44 @@ static void itemHelp(FILE * fp,
* @param con context
* @param fp output file handle
* @param table option(s)
- * @param columns output display width control
+ * @param left
* @param translation_domain translation domain
*/
static void singleTableHelp(poptContext con, FILE * fp,
- /*@null@*/ const struct poptOption * table,
- columns_t columns,
+ /*@null@*/ const struct poptOption * table, int left,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
- /*@modifies fp, columns->cur, fileSystem @*/
+ /*@modifies *fp, fileSystem @*/
{
const struct poptOption * opt;
const char *sub_transdom;
- int xx;
if (table == poptAliasOptions) {
- itemHelp(fp, con->aliases, con->numAliases, columns, NULL);
- itemHelp(fp, con->execs, con->numExecs, columns, NULL);
+ itemHelp(fp, con->aliases, con->numAliases, left, NULL);
+ itemHelp(fp, con->execs, con->numExecs, left, NULL);
return;
}
if (table != NULL)
- for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
- if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN))
- singleOptionHelp(fp, columns, opt, translation_domain);
+ for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
+ if ((opt->longName || opt->shortName) &&
+ !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
+ singleOptionHelp(fp, left, opt, translation_domain);
}
if (table != NULL)
- for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
- if (poptArgType(opt) != POPT_ARG_INCLUDE_TABLE)
+ for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
+ if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_INCLUDE_TABLE)
continue;
- sub_transdom = getTableTranslationDomain(opt->arg);
+ sub_transdom = getTableTranslationDomain(
+ (const struct poptOption *)opt->arg);
if (sub_transdom == NULL)
sub_transdom = translation_domain;
- /* If no popt aliases/execs, skip poptAliasOption processing. */
- if (opt->arg == poptAliasOptions && !(con->numAliases || con->numExecs))
- continue;
if (opt->descrip)
- xx = POPT_fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
+ fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
- singleTableHelp(con, fp, opt->arg, columns, sub_transdom);
+ singleTableHelp(con, fp, (const struct poptOption *)opt->arg, left, sub_transdom);
}
}
@@ -639,20 +478,22 @@ static void singleTableHelp(poptContext con, FILE * fp,
* @param con context
* @param fp output file handle
*/
-static size_t showHelpIntro(poptContext con, FILE * fp)
+static int showHelpIntro(poptContext con, FILE * fp)
/*@globals fileSystem @*/
- /*@modifies fp, fileSystem @*/
+ /*@modifies *fp, fileSystem @*/
{
- size_t len = (size_t)6;
- int xx;
+ int len = 6;
+ const char * fn;
- xx = POPT_fprintf(fp, POPT_("Usage:"));
+ fprintf(fp, POPT_("Usage:"));
if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
- struct optionStackEntry * os = con->optionStack;
- const char * fn = (os->argv ? os->argv[0] : NULL);
+/*@-boundsread@*/
+ /*@-nullderef@*/ /* LCL: wazzup? */
+ fn = con->optionStack->argv[0];
+ /*@=nullderef@*/
+/*@=boundsread@*/
if (fn == NULL) return len;
if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
- /* XXX POPT_fprintf not needed for argv[0] display. */
fprintf(fp, " %s", fn);
len += strlen(fn) + 1;
}
@@ -660,119 +501,108 @@ static size_t showHelpIntro(poptContext con, FILE * fp)
return len;
}
-void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags))
+void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags)
{
- columns_t columns = calloc((size_t)1, sizeof(*columns));
- int xx;
+ int leftColWidth;
(void) showHelpIntro(con, fp);
if (con->otherHelp)
- xx = POPT_fprintf(fp, " %s\n", con->otherHelp);
+ fprintf(fp, " %s\n", con->otherHelp);
else
- xx = POPT_fprintf(fp, " %s\n", POPT_("[OPTION...]"));
+ fprintf(fp, " %s\n", POPT_("[OPTION...]"));
- if (columns) {
- columns->cur = maxArgWidth(con->options, NULL);
- columns->max = maxColumnWidth(fp);
- singleTableHelp(con, fp, con->options, columns, NULL);
- free(columns);
- }
+ leftColWidth = maxArgWidth(con->options, NULL);
+ singleTableHelp(con, fp, con->options, leftColWidth, NULL);
}
/**
- * Display usage text for an option.
* @param fp output file handle
- * @param columns output display width control
+ * @param cursor
* @param opt option(s)
* @param translation_domain translation domain
*/
-static size_t singleOptionUsage(FILE * fp, columns_t columns,
+static int singleOptionUsage(FILE * fp, int cursor,
const struct poptOption * opt,
/*@null@*/ const char *translation_domain)
/*@globals fileSystem @*/
- /*@modifies fp, columns->cur, fileSystem @*/
+ /*@modifies *fp, fileSystem @*/
{
- size_t len = sizeof(" []")-1;
+ int len = 4;
+ char shortStr[2] = { '\0', '\0' };
+ const char * item = shortStr;
const char * argDescrip = getArgDescrip(opt, translation_domain);
- /* Display shortName iff printable non-space. */
- int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' ');
-
-#define prtlong (opt->longName != NULL) /* XXX splint needs a clue */
- if (!(prtshort || prtlong))
- return columns->cur;
-
- len = sizeof(" []")-1;
- if (prtshort)
- len += sizeof("-c")-1;
- if (prtlong) {
- if (prtshort) len += sizeof("|")-1;
- len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1;
+
+ if (opt->shortName != '\0' && opt->longName != NULL) {
+ len += 2;
+ if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++;
+ len += strlen(opt->longName);
+ } else if (opt->shortName != '\0') {
+ len++;
+ shortStr[0] = opt->shortName;
+ shortStr[1] = '\0';
+ } else if (opt->longName) {
len += strlen(opt->longName);
+ if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++;
+ item = opt->longName;
}
- if (argDescrip) {
-
- /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */
- if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1;
+ if (len == 4) return cursor;
- /* Adjust for (possible) wide characters. */
- len += stringDisplayWidth(argDescrip);
- }
+ if (argDescrip)
+ len += strlen(argDescrip) + 1;
- if ((columns->cur + len) > columns->max) {
+ if ((cursor + len) > 79) {
fprintf(fp, "\n ");
- columns->cur = (size_t)7;
+ cursor = 7;
}
- fprintf(fp, " [");
- if (prtshort)
- fprintf(fp, "-%c", opt->shortName);
- if (prtlong)
- fprintf(fp, "%s%s%s",
- (prtshort ? "|" : ""),
- (F_ISSET(opt, ONEDASH) ? "-" : "--"),
- opt->longName);
-#undef prtlong
-
- if (argDescrip) {
- /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */
- if (!strchr(" =(", argDescrip[0])) fprintf(fp, "=");
- fprintf(fp, "%s", argDescrip);
+ if (opt->longName && opt->shortName) {
+ fprintf(fp, " [-%c|-%s%s%s%s]",
+ opt->shortName, ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "" : "-"),
+ opt->longName,
+ (argDescrip ? " " : ""),
+ (argDescrip ? argDescrip : ""));
+ } else {
+ fprintf(fp, " [-%s%s%s%s]",
+ ((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"),
+ item,
+ (argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""),
+ (argDescrip ? argDescrip : ""));
}
- fprintf(fp, "]");
- return columns->cur + len + 1;
+ return cursor + len + 1;
}
/**
* Display popt alias and exec usage.
* @param fp output file handle
- * @param columns output display width control
+ * @param cursor
* @param item alias/exec array
* @param nitems no. of ara/exec entries
* @param translation_domain translation domain
*/
-static size_t itemUsage(FILE * fp, columns_t columns,
- /*@null@*/ poptItem item, int nitems,
+static int itemUsage(FILE * fp, int cursor, poptItem item, int nitems,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
- /*@modifies fp, columns->cur, fileSystem @*/
+ /*@modifies *fp, fileSystem @*/
{
int i;
+ /*@-branchstate@*/ /* FIX: W2DO? */
if (item != NULL)
for (i = 0; i < nitems; i++, item++) {
const struct poptOption * opt;
opt = &item->option;
- if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) {
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
translation_domain = (const char *)opt->arg;
- } else
- if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) {
- columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
+ } else if ((opt->longName || opt->shortName) &&
+ !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
+ cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
}
}
+ /*@=branchstate@*/
- return columns->cur;
+ return cursor;
}
/**
@@ -781,7 +611,6 @@ static size_t itemUsage(FILE * fp, columns_t columns,
typedef struct poptDone_s {
int nopts;
int maxopts;
-/*@null@*/
const void ** opts;
} * poptDone;
@@ -789,30 +618,31 @@ typedef struct poptDone_s {
* Display usage text for a table of options.
* @param con context
* @param fp output file handle
- * @param columns output display width control
+ * @param cursor
* @param opt option(s)
* @param translation_domain translation domain
* @param done tables already processed
* @return
*/
-static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns,
+static int singleTableUsage(poptContext con, FILE * fp, int cursor,
/*@null@*/ const struct poptOption * opt,
/*@null@*/ const char * translation_domain,
/*@null@*/ poptDone done)
/*@globals fileSystem @*/
- /*@modifies fp, columns->cur, done, fileSystem @*/
+ /*@modifies *fp, done, fileSystem @*/
{
+ /*@-branchstate@*/ /* FIX: W2DO? */
if (opt != NULL)
for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
- if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) {
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
translation_domain = (const char *)opt->arg;
- } else
- if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) {
+ } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
if (done) {
int i = 0;
- if (done->opts != NULL)
for (i = 0; i < done->nopts; i++) {
+/*@-boundsread@*/
const void * that = done->opts[i];
+/*@=boundsread@*/
if (that == NULL || that != opt->arg)
/*@innercontinue@*/ continue;
/*@innerbreak@*/ break;
@@ -820,18 +650,21 @@ static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns,
/* Skip if this table has already been processed. */
if (opt->arg == NULL || i < done->nopts)
continue;
- if (done->opts != NULL && done->nopts < done->maxopts)
+/*@-boundswrite@*/
+ if (done->nopts < done->maxopts)
done->opts[done->nopts++] = (const void *) opt->arg;
+/*@=boundswrite@*/
}
- columns->cur = singleTableUsage(con, fp, columns, opt->arg,
+ cursor = singleTableUsage(con, fp, cursor, (const struct poptOption *)opt->arg,
translation_domain, done);
- } else
- if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) {
- columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
+ } else if ((opt->longName || opt->shortName) &&
+ !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
+ cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
}
}
+ /*@=branchstate@*/
- return columns->cur;
+ return cursor;
}
/**
@@ -842,84 +675,67 @@ static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns,
* @retval str concatenation of short options
* @return length of display string
*/
-static size_t showShortOptions(const struct poptOption * opt, FILE * fp,
+static int showShortOptions(const struct poptOption * opt, FILE * fp,
/*@null@*/ char * str)
/*@globals fileSystem @*/
- /*@modifies str, *fp, fileSystem @*/
+ /*@modifies *str, *fp, fileSystem @*/
/*@requires maxRead(str) >= 0 @*/
{
- /* bufsize larger then the ascii set, lazy allocation on top level call. */
- size_t nb = (size_t)300;
- char * s = (str != NULL ? str : calloc((size_t)1, nb));
- size_t len = (size_t)0;
-
- if (s == NULL)
- return 0;
+ /* bufsize larger then the ascii set, lazy alloca on top level call. */
+ char * s = (str != NULL ? str : (char *)memset(alloca(300), 0, 300));
+ int len = 0;
+/*@-boundswrite@*/
if (opt != NULL)
for (; (opt->longName || opt->shortName || opt->arg); opt++) {
- if (!F_ISSET(opt, DOC_HIDDEN) && opt->shortName && !poptArgType(opt))
- {
- /* Display shortName iff unique printable non-space. */
- if (!strchr(s, opt->shortName) && isprint((int)opt->shortName)
- && opt->shortName != ' ')
- s[strlen(s)] = opt->shortName;
- } else if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE)
+ if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
+ s[strlen(s)] = opt->shortName;
+ else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
if (opt->arg) /* XXX program error */
- len = showShortOptions(opt->arg, fp, s);
+ len = showShortOptions(
+ (const struct poptOption *)opt->arg, fp, s);
}
+/*@=boundswrite@*/
/* On return to top level, print the short options, return print length. */
- if (s != str && *s != '\0') {
+ if (s == str && *s != '\0') {
fprintf(fp, " [-%s]", s);
len = strlen(s) + sizeof(" [-]")-1;
}
-/*@-temptrans@*/ /* LCL: local s, not str arg, is being freed. */
- if (s != str)
- free(s);
-/*@=temptrans@*/
return len;
}
-void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags))
+void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags)
{
- columns_t columns = calloc((size_t)1, sizeof(*columns));
- struct poptDone_s done_buf;
- poptDone done = &done_buf;
+ poptDone done = (poptDone)memset(alloca(sizeof(*done)), 0, sizeof(*done));
+ int cursor;
- memset(done, 0, sizeof(*done));
done->nopts = 0;
done->maxopts = 64;
- if (columns) {
- columns->cur = done->maxopts * sizeof(*done->opts);
- columns->max = maxColumnWidth(fp);
- done->opts = calloc((size_t)1, columns->cur);
- /*@-keeptrans@*/
- if (done->opts != NULL)
- done->opts[done->nopts++] = (const void *) con->options;
- /*@=keeptrans@*/
-
- columns->cur = showHelpIntro(con, fp);
- columns->cur += showShortOptions(con->options, fp, NULL);
- columns->cur = singleTableUsage(con, fp, columns, con->options, NULL, done);
- columns->cur = itemUsage(fp, columns, con->aliases, con->numAliases, NULL);
- columns->cur = itemUsage(fp, columns, con->execs, con->numExecs, NULL);
+ cursor = done->maxopts * sizeof(*done->opts);
+/*@-boundswrite@*/
+ done->opts = (const void **)memset(alloca(cursor), 0, cursor);
+ done->opts[done->nopts++] = (const void *) con->options;
+/*@=boundswrite@*/
+
+ cursor = showHelpIntro(con, fp);
+ cursor += showShortOptions(con->options, fp, NULL);
+ cursor = singleTableUsage(con, fp, cursor, con->options, NULL, done);
+ cursor = itemUsage(fp, cursor, con->aliases, con->numAliases, NULL);
+ cursor = itemUsage(fp, cursor, con->execs, con->numExecs, NULL);
if (con->otherHelp) {
- columns->cur += strlen(con->otherHelp) + 1;
- if (columns->cur > columns->max) fprintf(fp, "\n ");
+ cursor += strlen(con->otherHelp) + 1;
+ if (cursor > 79) fprintf(fp, "\n ");
fprintf(fp, " %s", con->otherHelp);
}
fprintf(fp, "\n");
- if (done->opts != NULL)
- free(done->opts);
- free(columns);
- }
}
void poptSetOtherOptionHelp(poptContext con, const char * text)
{
- con->otherHelp = _free(con->otherHelp);
+ con->otherHelp = (const char *)_free(con->otherHelp);
con->otherHelp = xstrdup(text);
}
+/*@=type@*/
diff --git a/third_party/popt/poptint.c b/third_party/popt/poptint.c
deleted file mode 100644
index 1af46ff..0000000
--- a/third_party/popt/poptint.c
+++ /dev/null
@@ -1,199 +0,0 @@
-#include "system.h"
-#include <stdarg.h>
-#include "poptint.h"
-
-/* Any pair of 32 bit hashes can be used. lookup3.c generates pairs, will do. */
-#define _JLU3_jlu32lpair 1
-#define jlu32lpair poptJlu32lpair
-#include "lookup3.c"
-
-/*@-varuse +charint +ignoresigns @*/
-/*@unchecked@*/ /*@observer@*/
-static const unsigned char utf8_skip_data[256] = {
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
-};
-/*@=varuse =charint =ignoresigns @*/
-
-const char *
-POPT_prev_char (const char *str)
-{
- const char *p = str;
-
- while (1) {
- p--;
- if (((unsigned)*p & 0xc0) != (unsigned)0x80)
- return p;
- }
-}
-
-const char *
-POPT_next_char (const char *str)
-{
- const char *p = str;
-
- while (*p != '\0') {
- p++;
- if (((unsigned)*p & 0xc0) != (unsigned)0x80)
- break;
- }
- return p;
-}
-
-#if !defined(POPT_fprintf) /* XXX lose all the goop ... */
-
-#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__)
-/*
- * Rebind a "UTF-8" codeset for popt's internal use.
- */
-char *
-POPT_dgettext(const char * dom, const char * str)
-{
- char * codeset = NULL;
- char * retval = NULL;
-
- if (!dom)
- dom = textdomain(NULL);
- codeset = bind_textdomain_codeset(dom, NULL);
- bind_textdomain_codeset(dom, "UTF-8");
- retval = dgettext(dom, str);
- bind_textdomain_codeset(dom, codeset);
-
- return retval;
-}
-#endif
-
-#ifdef HAVE_ICONV
-/**
- * Return malloc'd string converted from UTF-8 to current locale.
- * @param istr input string (UTF-8 encoding assumed)
- * @return localized string
- */
-static /*@only@*/ /*@null@*/ char *
-strdup_locale_from_utf8 (/*@null@*/ char * istr)
- /*@*/
-{
- char * codeset = NULL;
- char * ostr = NULL;
- iconv_t cd;
-
- if (istr == NULL)
- return NULL;
-
-#ifdef HAVE_LANGINFO_H
- codeset = nl_langinfo ((nl_item)CODESET);
-#endif
-
- if (codeset != NULL && strcmp(codeset, "UTF-8") != 0
- && (cd = iconv_open(codeset, "UTF-8")) != (iconv_t)-1)
- {
- char * shift_pin = NULL;
- size_t db = strlen(istr);
-/*@owned@*/
- char * dstr = malloc((db + 1) * sizeof(*dstr));
- char * pin = istr;
- char * pout = dstr;
- size_t ib = db;
- size_t ob = db;
- size_t err;
-
- if (dstr == NULL)
- return NULL;
- err = iconv(cd, NULL, NULL, NULL, NULL);
- while (1) {
- *pout = '\0';
- err = iconv(cd, &pin, &ib, &pout, &ob);
- if (err != (size_t)-1) {
- if (shift_pin == NULL) {
- shift_pin = pin;
- pin = NULL;
- ib = 0;
- continue;
- }
- } else
- switch (errno) {
- case E2BIG:
- { size_t used = (size_t)(pout - dstr);
- db *= 2;
- dstr = realloc(dstr, (db + 1) * sizeof(*dstr));
- if (dstr != NULL) {
- pout = dstr + used;
- ob = db - used;
- continue;
- }
- } /*@switchbreak@*/ break;
- case EINVAL:
- case EILSEQ:
- default:
- /*@switchbreak@*/ break;
- }
- break;
- }
- (void) iconv_close(cd);
- *pout = '\0';
- ostr = xstrdup(dstr);
- free(dstr);
- } else
- ostr = xstrdup(istr);
-
- return ostr;
-}
-#endif
-
-int
-POPT_fprintf (FILE * stream, const char * format, ...)
-{
- char * b = NULL, * ob = NULL;
- int rc;
- va_list ap;
-
-#if defined(HAVE_VASPRINTF) && !defined(__LCLINT__)
- va_start(ap, format);
- if ((rc = vasprintf(&b, format, ap)) < 0)
- b = NULL;
- va_end(ap);
-#else
- size_t nb = (size_t)1;
-
- /* HACK: add +1 to the realloc no. of bytes "just in case". */
- /* XXX Likely unneeded, the issues wrto vsnprintf(3) return b0rkage have
- * to do with whether the final '\0' is counted (or not). The code
- * below already adds +1 for the (possibly already counted) trailing NUL.
- */
- while ((b = realloc(b, nb+1)) != NULL) {
- va_start(ap, format);
- rc = vsnprintf(b, nb, format, ap);
- va_end(ap);
- if (rc > -1) { /* glibc 2.1 */
- if ((size_t)rc < nb)
- break;
- nb = (size_t)(rc + 1); /* precise buffer length known */
- } else /* glibc 2.0 */
- nb += (nb < (size_t)100 ? (size_t)100 : nb);
- ob = b;
- }
-#endif
-
- rc = 0;
- if (b != NULL) {
-#ifdef HAVE_ICONV
- ob = strdup_locale_from_utf8(b);
- if (ob != NULL) {
- rc = fprintf(stream, "%s", ob);
- free(ob);
- } else
-#endif
- rc = fprintf(stream, "%s", b);
- free (b);
- }
-
- return rc;
-}
-
-#endif /* !defined(POPT_fprintf) */
diff --git a/third_party/popt/poptint.h b/third_party/popt/poptint.h
index 80cbaca..5d308ef 100644
--- a/third_party/popt/poptint.h
+++ b/third_party/popt/poptint.h
@@ -9,8 +9,6 @@
#ifndef H_POPTINT
#define H_POPTINT
-#include <stdint.h>
-
/**
* Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
* @param p memory to free
@@ -44,67 +42,15 @@ typedef struct {
#define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d))
#define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0)
-extern void poptJlu32lpair(/*@null@*/ const void *key, size_t size,
- uint32_t *pc, uint32_t *pb)
- /*@modifies *pc, *pb@*/;
-
-/** \ingroup popt
- * Typedef's for string and array of strings.
- */
-/*@-exporttype@*/
-typedef const char * poptString;
-typedef poptString * poptArgv;
-/*@=exporttype@*/
-
-/** \ingroup popt
- * A union to simplify opt->arg access without casting.
- */
-/*@-exporttype -fielduse@*/
-typedef union poptArg_u {
-/*@shared@*/
- void * ptr;
- int * intp;
- short * shortp;
- long * longp;
- long long * longlongp;
- float * floatp;
- double * doublep;
- const char ** argv;
- poptCallbackType cb;
-/*@shared@*/
- poptOption opt;
-} poptArg;
-/*@=exporttype =fielduse@*/
-
-/*@-exportvar@*/
-/*@unchecked@*/
-extern unsigned int _poptArgMask;
-/*@unchecked@*/
-extern unsigned int _poptGroupMask;
-/*@=exportvar@*/
-
-#define poptArgType(_opt) ((_opt)->argInfo & _poptArgMask)
-#define poptGroup(_opt) ((_opt)->argInfo & _poptGroupMask)
-
-#define F_ISSET(_opt, _FLAG) ((_opt)->argInfo & POPT_ARGFLAG_##_FLAG)
-#define LF_ISSET(_FLAG) (argInfo & POPT_ARGFLAG_##_FLAG)
-#define CBF_ISSET(_opt, _FLAG) ((_opt)->argInfo & POPT_CBFLAG_##_FLAG)
-
-/* XXX sick hack to preserve pretense of a popt-1.x ABI. */
-#define poptSubstituteHelpI18N(opt) \
- { /*@-observertrans@*/ \
- if ((opt) == poptHelpOptions) (opt) = poptHelpOptionsI18N; \
- /*@=observertrans@*/ }
-
struct optionStackEntry {
int argc;
/*@only@*/ /*@null@*/
- poptArgv argv;
+ const char ** argv;
/*@only@*/ /*@null@*/
pbm_set * argb;
int next;
/*@only@*/ /*@null@*/
- char * nextArg;
+ const char * nextArg;
/*@observer@*/ /*@null@*/
const char * nextCharArg;
/*@dependent@*/ /*@null@*/
@@ -117,7 +63,7 @@ struct poptContext_s {
/*@dependent@*/
struct optionStackEntry * os;
/*@owned@*/ /*@null@*/
- poptArgv leftovers;
+ const char ** leftovers;
int numLeftovers;
int nextLeftover;
/*@keep@*/
@@ -128,90 +74,37 @@ struct poptContext_s {
/*@only@*/ /*@null@*/
poptItem aliases;
int numAliases;
- unsigned int flags;
+ int flags;
/*@owned@*/ /*@null@*/
poptItem execs;
int numExecs;
/*@only@*/ /*@null@*/
- poptArgv finalArgv;
+ const char ** finalArgv;
int finalArgvCount;
int finalArgvAlloced;
-/*@null@*/
- int (*maincall) (int argc, const char **argv);
/*@dependent@*/ /*@null@*/
poptItem doExec;
-/*@only@*/ /*@null@*/
+/*@only@*/
const char * execPath;
int execAbsolute;
-/*@only@*/ /*@relnull@*/
+/*@only@*/
const char * otherHelp;
/*@null@*/
pbm_set * arg_strip;
};
-#if defined(POPT_fprintf)
-#define POPT_dgettext dgettext
-#else
-#ifdef HAVE_ICONV
-#include <iconv.h>
-#if defined(__LCLINT__)
-/*@-declundef -incondefs @*/
-extern /*@only@*/ iconv_t iconv_open(const char *__tocode, const char *__fromcode)
- /*@*/;
-
-extern size_t iconv(iconv_t __cd, /*@null@*/ char ** __inbuf,
- /*@null@*/ /*@out@*/ size_t * __inbytesleft,
- /*@null@*/ /*@out@*/ char ** __outbuf,
- /*@null@*/ /*@out@*/ size_t * __outbytesleft)
- /*@modifies __cd,
- *__inbuf, *__inbytesleft, *__outbuf, *__outbytesleft @*/;
-
-extern int iconv_close(/*@only@*/ iconv_t __cd)
- /*@modifies __cd @*/;
-/*@=declundef =incondefs @*/
-#endif
-#endif
-
-#ifdef HAVE_LANGINFO_H
-#include <langinfo.h>
-#if defined(__LCLINT__)
-/*@-declundef -incondefs @*/
-extern char *nl_langinfo (nl_item __item)
- /*@*/;
-/*@=declundef =incondefs @*/
-#endif
-#endif
-
-#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__)
-char *POPT_dgettext(const char * dom, const char * str)
- /*@*/;
-#endif
-
-int POPT_fprintf (FILE* stream, const char *format, ...)
- /*@globals fileSystem @*/
- /*@modifies stream, fileSystem @*/;
-#endif /* !defined(POPT_fprintf) */
-
-const char *POPT_prev_char (/*@returned@*/ const char *str)
- /*@*/;
-
-const char *POPT_next_char (/*@returned@*/ const char *str)
- /*@*/;
-
-#endif
-
-#if defined(ENABLE_NLS) && defined(HAVE_LIBINTL_H)
+#ifdef HAVE_LIBINTL_H
#include <libintl.h>
#endif
-#if defined(ENABLE_NLS) && defined(HAVE_GETTEXT) && !defined(__LCLINT__)
+#if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
#define _(foo) gettext(foo)
#else
#define _(foo) foo
#endif
-#if defined(ENABLE_NLS) && defined(HAVE_DCGETTEXT) && !defined(__LCLINT__)
-#define D_(dom, str) POPT_dgettext(dom, str)
+#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__)
+#define D_(dom, str) dgettext(dom, str)
#define POPT_(foo) D_("popt", foo)
#else
#define D_(dom, str) str
@@ -220,3 +113,4 @@ const char *POPT_next_char (/*@returned@*/ const char *str)
#define N_(foo) foo
+#endif
diff --git a/third_party/popt/poptparse.c b/third_party/popt/poptparse.c
index 39bf1aa..b03deef 100644
--- a/third_party/popt/poptparse.c
+++ b/third_party/popt/poptparse.c
@@ -10,6 +10,7 @@
#define POPT_ARGV_ARRAY_GROW_DELTA 5
+/*@-boundswrite@*/
int poptDupArgv(int argc, const char **argv,
int * argcPtr, const char *** argvPtr)
{
@@ -26,18 +27,18 @@ int poptDupArgv(int argc, const char **argv,
nb += strlen(argv[i]) + 1;
}
- dst = malloc(nb);
+ dst = (char *)malloc(nb);
if (dst == NULL) /* XXX can't happen */
return POPT_ERROR_MALLOC;
- argv2 = (void *) dst;
+ argv2 = (const char **) dst;
dst += (argc + 1) * sizeof(*argv);
- *dst = '\0';
+ /*@-branchstate@*/
for (i = 0; i < argc; i++) {
argv2[i] = dst;
- dst = stpcpy(dst, argv[i]);
- dst++; /* trailing NUL */
+ dst += strlen(strcpy(dst, argv[i])) + 1;
}
+ /*@=branchstate@*/
argv2[argc] = NULL;
if (argvPtr) {
@@ -50,24 +51,21 @@ int poptDupArgv(int argc, const char **argv,
*argcPtr = argc;
return 0;
}
+/*@=boundswrite@*/
+/*@-bounds@*/
int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
{
const char * src;
char quote = '\0';
int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
- const char ** argv = malloc(sizeof(*argv) * argvAlloced);
+ const char ** argv = (const char **)malloc(sizeof(*argv) * argvAlloced);
int argc = 0;
- size_t buflen = strlen(s) + 1;
- char * buf, * bufOrig = NULL;
+ int buflen = strlen(s) + 1;
+ char * buf = (char*)memset(alloca(buflen), 0, buflen);
int rc = POPT_ERROR_MALLOC;
if (argv == NULL) return rc;
- buf = bufOrig = calloc((size_t)1, buflen);
- if (buf == NULL) {
- free(argv);
- return rc;
- }
argv[argc] = buf;
for (src = s; *src != '\0'; src++) {
@@ -83,12 +81,12 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
if (*src != quote) *buf++ = '\\';
}
*buf++ = *src;
- } else if (_isspaceptr(src)) {
+ } else if (isspace(*src)) {
if (*argv[argc] != '\0') {
buf++, argc++;
if (argc == argvAlloced) {
argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
- argv = realloc(argv, sizeof(*argv) * argvAlloced);
+ argv = (const char **)realloc(argv, sizeof(*argv) * argvAlloced);
if (argv == NULL) goto exit;
}
argv[argc] = buf;
@@ -118,29 +116,29 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
exit:
- if (bufOrig) free(bufOrig);
if (argv) free(argv);
return rc;
}
+/*@=bounds@*/
/* still in the dev stage.
* return values, perhaps 1== file erro
* 2== line to long
* 3== umm.... more?
*/
-int poptConfigFileToString(FILE *fp, char ** argstrp,
- /*@unused@*/ UNUSED(int flags))
+int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ int flags)
{
char line[999];
char * argstr;
char * p;
char * q;
char * x;
- size_t t;
- size_t argvlen = 0;
+ int t;
+ int argvlen = 0;
size_t maxlinelen = sizeof(line);
size_t linelen;
- size_t maxargvlen = (size_t)480;
+ int maxargvlen = 480;
+ int linenum = 0;
*argstrp = NULL;
@@ -151,42 +149,41 @@ int poptConfigFileToString(FILE *fp, char ** argstrp,
if (fp == NULL)
return POPT_ERROR_NULLARG;
- argstr = calloc(maxargvlen, sizeof(*argstr));
+ argstr = (char *)calloc(maxargvlen, sizeof(*argstr));
if (argstr == NULL) return POPT_ERROR_MALLOC;
while (fgets(line, (int)maxlinelen, fp) != NULL) {
+ linenum++;
p = line;
/* loop until first non-space char or EOL */
- while( *p != '\0' && _isspaceptr(p) )
+ while( *p != '\0' && isspace(*p) )
p++;
linelen = strlen(p);
- if (linelen >= maxlinelen-1) {
- free(argstr);
+ if (linelen >= maxlinelen-1)
return POPT_ERROR_OVERFLOW; /* XXX line too long */
- }
if (*p == '\0' || *p == '\n') continue; /* line is empty */
if (*p == '#') continue; /* comment line */
q = p;
- while (*q != '\0' && (!_isspaceptr(q)) && *q != '=')
+ while (*q != '\0' && (!isspace(*q)) && *q != '=')
q++;
- if (_isspaceptr(q)) {
+ if (isspace(*q)) {
/* a space after the name, find next non space */
*q++='\0';
- while( *q != '\0' && _isspaceptr(q) ) q++;
+ while( *q != '\0' && isspace((int)*q) ) q++;
}
if (*q == '\0') {
/* single command line option (ie, no name=val, just name) */
q[-1] = '\0'; /* kill off newline from fgets() call */
- argvlen += (t = (size_t)(q - p)) + (sizeof(" --")-1);
+ argvlen += (t = q - p) + (sizeof(" --")-1);
if (argvlen >= maxargvlen) {
maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
- argstr = realloc(argstr, maxargvlen);
+ argstr = (char *)realloc(argstr, maxargvlen);
if (argstr == NULL) return POPT_ERROR_MALLOC;
}
strcat(argstr, " --");
@@ -200,22 +197,22 @@ int poptConfigFileToString(FILE *fp, char ** argstrp,
*q++ = '\0';
/* find next non-space letter of value */
- while (*q != '\0' && _isspaceptr(q))
+ while (*q != '\0' && isspace(*q))
q++;
if (*q == '\0')
continue; /* XXX silently ignore missing value */
/* now, loop and strip all ending whitespace */
x = p + linelen;
- while (_isspaceptr(--x))
- *x = '\0'; /* null out last char if space (including fgets() NL) */
+ while (isspace(*--x))
+ *x = 0; /* null out last char if space (including fgets() NL) */
/* rest of line accept */
- t = (size_t)(x - p);
+ t = x - p;
argvlen += t + (sizeof("' --='")-1);
if (argvlen >= maxargvlen) {
maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
- argstr = realloc(argstr, maxargvlen);
+ argstr = (char *)realloc(argstr, maxargvlen);
if (argstr == NULL) return POPT_ERROR_MALLOC;
}
strcat(argstr, " --");
diff --git a/third_party/popt/system.h b/third_party/popt/system.h
index 452bf40..bbb4f6c 100644
--- a/third_party/popt/system.h
+++ b/third_party/popt/system.h
@@ -1,7 +1,3 @@
-/**
- * \file popt/system.h
- */
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -17,14 +13,11 @@ extern __const __int32_t *__ctype_toupper;
#include <ctype.h>
-/* XXX isspace(3) has i18n encoding signednesss issues on Solaris. */
-#define _isspaceptr(_chp) isspace((int)(*(unsigned char *)(_chp)))
-
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
-#ifdef HAVE_MCHECK_H
+#if HAVE_MCHECK_H
#include <mcheck.h>
#endif
@@ -32,7 +25,7 @@ extern __const __int32_t *__ctype_toupper;
#include <stdlib.h>
#include <string.h>
-#if defined(HAVE_UNISTD_H) && !defined(__LCLINT__)
+#if HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -42,62 +35,44 @@ extern __const __int32_t *__ctype_toupper;
#include <libc.h>
#endif
-/*@-incondefs@*/
-/*@mayexit@*/ /*@only@*/ /*@out@*/ /*@unused@*/
-void * xmalloc (size_t size)
- /*@globals errno @*/
- /*@ensures maxSet(result) == (size - 1) @*/
- /*@modifies errno @*/;
-
-/*@mayexit@*/ /*@only@*/ /*@unused@*/
-void * xcalloc (size_t nmemb, size_t size)
- /*@ensures maxSet(result) == (nmemb - 1) @*/
+#if defined(__LCLINT__)
+/*@-declundef -incondefs -redecl@*/ /* LCL: missing annotation */
+/*@only@*/ void * alloca (size_t __size)
+ /*@ensures MaxSet(result) == (__size - 1) @*/
/*@*/;
+/*@=declundef =incondefs =redecl@*/
+#endif
-/*@mayexit@*/ /*@only@*/ /*@unused@*/
-void * xrealloc (/*@null@*/ /*@only@*/ void * ptr, size_t size)
- /*@ensures maxSet(result) == (size - 1) @*/
- /*@modifies *ptr @*/;
+/* AIX requires this to be the first thing in the file. */
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+#pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+#elif defined(__GNUC__) && defined(__STRICT_ANSI__)
+#define alloca __builtin_alloca
+#elif defined(__GNUC__) && defined(HAVE_ALLOCA_H)
+# include <alloca.h>
+#endif
-/*@mayexit@*/ /*@only@*/ /*@unused@*/
-char * xstrdup (const char *str)
+/*@-redecl -redef@*/
+/*@mayexit@*/ /*@only@*/ char * xstrdup (const char *str)
/*@*/;
-/*@=incondefs@*/
-
-#if !defined(HAVE_STPCPY)
-/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */
-static inline char * stpcpy (char *dest, const char * src) {
- register char *d = dest;
- register const char *s = src;
+/*@=redecl =redef@*/
- do
- *d++ = *s;
- while (*s++ != '\0');
- return d - 1;
-}
-#endif
-
-/* Memory allocation via macro defs to get meaningful locations from mtrace() */
-#if defined(HAVE_MCHECK_H) && defined(__GNUC__)
+#if HAVE_MCHECK_H && defined(__GNUC__)
#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL)
-#define xmalloc(_size) (malloc(_size) ? : vmefail())
-#define xcalloc(_nmemb, _size) (calloc((_nmemb), (_size)) ? : vmefail())
-#define xrealloc(_ptr, _size) (realloc((_ptr), (_size)) ? : vmefail())
#define xstrdup(_str) (strcpy((malloc(strlen(_str)+1) ? : vmefail()), (_str)))
#else
-#define xmalloc(_size) malloc(_size)
-#define xcalloc(_nmemb, _size) calloc((_nmemb), (_size))
-#define xrealloc(_ptr, _size) realloc((_ptr), (_size))
#define xstrdup(_str) strdup(_str)
-#endif /* defined(HAVE_MCHECK_H) && defined(__GNUC__) */
+#endif /* HAVE_MCHECK_H && defined(__GNUC__) */
-#if defined(HAVE___SECURE_GETENV) && !defined(__LCLINT__)
-#define getenv(_s) __secure_getenv(_s)
-#endif
-
-#if !defined(__GNUC__) && !defined(__attribute__)
-#define __attribute__(x)
-#endif
-#define UNUSED(x) x __attribute__((__unused__))
#include "popt.h"
diff --git a/third_party/popt/wscript b/third_party/popt/wscript
index eae8602..e81572c 100644
--- a/third_party/popt/wscript
+++ b/third_party/popt/wscript
@@ -4,7 +4,6 @@ import Options
def configure(conf):
conf.CHECK_HEADERS('float.h')
- conf.CHECK_FUNCS('stpcpy')
if conf.CHECK_POPT():
conf.define('USING_SYSTEM_POPT', 1)
@@ -13,9 +12,8 @@ def build(bld):
if bld.CONFIG_SET('USING_SYSTEM_POPT'):
return
- cflags = '-DPACKAGE="popt" -DPOPT_SYSCONFDIR="%s"' % bld.env.SYSCONFDIR
bld.SAMBA_LIBRARY('popt',
- source='popt.c poptconfig.c popthelp.c poptint.c poptparse.c',
- cflags=cflags,
+ source='findme.c popt.c poptconfig.c popthelp.c poptparse.c',
+ cflags='-DDBL_EPSILON=__DBL_EPSILON__',
allow_warnings=True,
private_library=True)
diff --git a/tools/ldbdump.c b/tools/ldbdump.c
index 4697661..c399b59 100644
--- a/tools/ldbdump.c
+++ b/tools/ldbdump.c
@@ -27,11 +27,6 @@
#include <ldb.h>
#include <ldb_private.h>
-#ifdef HAVE_LMDB
-#include <lmdb.h>
-#endif /* ifdef HAVE_LMDB */
-
-
static struct ldb_context *ldb;
bool show_index = false;
bool validate_contents = false;
@@ -171,116 +166,6 @@ static int dump_tdb(const char *fname, struct ldb_dn *dn, bool emergency)
return tdb_traverse(tdb, traverse_fn, dn) == -1 ? 1 : 0;
}
-#ifdef HAVE_LMDB
-static int dump_lmdb(const char *fname, struct ldb_dn *dn, bool emergency)
-{
- int ret;
- struct MDB_env *env = NULL;
- struct MDB_txn *txn = NULL;
- MDB_dbi dbi;
- struct MDB_cursor *cursor = NULL;
- struct MDB_val key;
- struct MDB_val data;
-
- ret = mdb_env_create(&env);
- if (ret != 0) {
- fprintf(stderr,
- "Could not create MDB environment: (%d) %s\n",
- ret,
- mdb_strerror(ret));
- goto close_env;
- }
-
- ret = mdb_env_open(env,
- fname,
- MDB_NOSUBDIR|MDB_NOTLS|MDB_RDONLY,
- 0600);
- if (ret != 0) {
- fprintf(stderr,
- "Could not open environment for %s: (%d) %s\n",
- fname,
- ret,
- mdb_strerror(ret));
- goto close_env;
- }
-
- ret = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
- if (ret != 0) {
- fprintf(stderr,
- "Could not start transaction: (%d) %s\n",
- ret,
- mdb_strerror(ret));
- goto close_env;
- }
-
- ret = mdb_dbi_open(txn, NULL, 0, &dbi);
- if (ret != 0) {
- fprintf(stderr,
- "Could not open database: (%d) %s\n",
- ret,
- mdb_strerror(ret));
- goto close_txn;
- }
-
- ret = mdb_cursor_open(txn, dbi, &cursor);
- if (ret != 0) {
- fprintf(stderr,
- "Could not open cursor: (%d) %s\n",
- ret,
- mdb_strerror(ret));
- goto close_txn;
- }
-
- ret = mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
- if (ret != 0 && ret != MDB_NOTFOUND) {
- fprintf(stderr,
- "Could not find first record: (%d) %s\n",
- ret,
- mdb_strerror(ret));
- goto close_cursor;
- }
- while (ret != MDB_NOTFOUND) {
- struct TDB_DATA tkey = {
- .dptr = key.mv_data,
- .dsize = key.mv_size
- };
- struct TDB_DATA tdata = {
- .dptr = data.mv_data,
- .dsize = data.mv_size
- };
- traverse_fn(NULL, tkey, tdata, dn);
- ret = mdb_cursor_get(cursor, &key, &data, MDB_NEXT);
- if (ret != 0 && ret != MDB_NOTFOUND) {
- fprintf(stderr,
- "Could not read next record: (%d) %s\n",
- ret,
- mdb_strerror(ret));
- goto close_cursor;
- }
- }
- ret = 0;
-
-close_cursor:
- mdb_cursor_close(cursor);
-close_txn:
- mdb_txn_commit(txn);
-close_env:
- mdb_env_close(env);
-
- if (ret != 0) {
- return 1;
- }
- return 0;
-
-}
-#else
-static int dump_lmdb(const char *fname, struct ldb_dn *dn, bool emergency)
-{
- /* not built with lmdb support */
- return 1;
-}
-#endif /* #ifdef HAVE_LMDB */
-
static void usage( void)
{
printf( "Usage: ldbdump [options] <filename>\n\n");
@@ -344,14 +229,5 @@ static void usage( void)
fname = argv[optind];
- rc = dump_lmdb(fname, dn, emergency);
- if (rc != 0) {
- rc = dump_tdb(fname, dn, emergency);
- if (rc != 0) {
- fprintf(stderr, "Failed to open %s\n", fname);
- return 1;
- }
- }
- return 0;
-
+ return dump_tdb(fname, dn, emergency);
}
diff --git a/wscript b/wscript
index f5cb1e0..5b7f364 100644
--- a/wscript
+++ b/wscript
@@ -1,12 +1,11 @@
#!/usr/bin/env python
APPNAME = 'ldb'
-VERSION = '1.4.0'
+VERSION = '1.3.5'
blddir = 'bin'
import sys, os
-import Logs
# find the buildtools directory
srcdir = '.'
@@ -14,7 +13,7 @@ while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5:
srcdir = srcdir + '/..'
sys.path.insert(0, srcdir + '/buildtools/wafsamba')
-import wafsamba, samba_dist, Utils, Options
+import wafsamba, samba_dist, Utils
samba_dist.DIST_DIRS('''lib/ldb:. lib/replace:lib/replace lib/talloc:lib/talloc
lib/tdb:lib/tdb lib/tdb:lib/tdb lib/tevent:lib/tevent
@@ -32,11 +31,6 @@ def set_options(opt):
opt.RECURSE('lib/replace')
opt.tool_options('python') # options for disabling pyc or pyo compilation
- opt.add_option('--without-ldb-lmdb',
- help='disable new LMDB backend for LDB',
- action='store_true', dest='without_ldb_lmdb', default=False)
-
-
def configure(conf):
conf.RECURSE('lib/tdb')
conf.RECURSE('lib/tevent')
@@ -98,41 +92,6 @@ def configure(conf):
implied_deps='replace talloc tdb tevent'):
conf.define('USING_SYSTEM_LDB', 1)
- if not conf.CHECK_CODE('return !(sizeof(size_t) >= 8)',
- "HAVE_64_BIT_SIZE_T_FOR_LMDB",
- execute=True,
- msg='Checking for a 64-bit host to '
- 'support lmdb'):
- Logs.warn("--without-ldb-lmdb implied as this "
- "host is not 64-bit")
-
- if not conf.env.standalone_ldb and \
- not Options.options.without_ad_dc and \
- conf.CONFIG_GET('ENABLE_SELFTEST'):
- Logs.warn("NOTE: Some AD DC parts of selftest will fail")
-
- conf.env.REQUIRE_LMDB = False
- else:
- if conf.env.standalone_ldb:
- if Options.options.without_ldb_lmdb:
- conf.env.REQUIRE_LMDB = False
- else:
- conf.env.REQUIRE_LMDB = True
- elif Options.options.without_ad_dc:
- conf.env.REQUIRE_LMDB = False
- else:
- if Options.options.without_ldb_lmdb:
- if not Options.options.without_ad_dc and \
- conf.CONFIG_GET('ENABLE_SELFTEST'):
- raise Utils.WafError('--without-ldb-lmdb conflicts '
- 'with --enable-selftest while '
- 'building the AD DC')
-
- conf.env.REQUIRE_LMDB = False
- else:
- conf.env.REQUIRE_LMDB = True
-
-
if conf.CONFIG_SET('USING_SYSTEM_LDB'):
v = VERSION.split('.')
conf.DEFINE('EXPECTED_SYSTEM_LDB_VERSION_MAJOR', int(v[0]))
@@ -151,39 +110,6 @@ def configure(conf):
if not sys.platform.startswith("openbsd"):
conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True)
- # if lmdb support is enabled then we require lmdb
- # is present, build the mdb back end and enable lmdb support in
- # the tools.
- if conf.env.REQUIRE_LMDB and \
- not conf.CONFIG_SET('USING_SYSTEM_LDB'):
- if not conf.CHECK_CFG(package='lmdb',
- args='"lmdb >= 0.9.16" --cflags --libs',
- msg='Checking for lmdb >= 0.9.16',
- mandatory=False):
- if not conf.CHECK_CODE('''
- #if MDB_VERSION_MAJOR == 0 \
- && MDB_VERSION_MINOR <= 9 \
- && MDB_VERSION_PATCH < 16
- #error LMDB too old
- #endif
- ''',
- 'HAVE_GOOD_LMDB_VERSION',
- headers='lmdb.h',
- msg='Checking for lmdb >= 0.9.16 via header check'):
-
- if conf.env.standalone_ldb:
- raise Utils.WafError('ldb build (unless --without-ldb-lmdb) '
- 'requires '
- 'lmdb 0.9.16 or later')
- elif not Options.options.without_ad_dc:
- raise Utils.WafError('Samba AD DC and --enable-selftest '
- 'requires '
- 'lmdb 0.9.16 or later')
-
- if conf.CHECK_FUNCS_IN('mdb_env_create', 'lmdb', headers='lmdb.h'):
- conf.DEFINE('HAVE_LMDB', '1')
-
-
conf.DEFINE('HAVE_CONFIG_H', 1, add_to_cflags=True)
conf.SAMBA_CONFIG_H()
@@ -201,15 +127,9 @@ def build(bld):
bld.RECURSE('lib/tdb')
if bld.env.standalone_ldb:
- if not 'PACKAGE_VERSION' in bld.env:
- bld.env.PACKAGE_VERSION = VERSION
- bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig'
private_library = False
else:
private_library = True
- # we're not currently linking against the ldap libs, but ldb.pc.in
- # has @LDAP_LIBS@
- bld.env.LDAP_LIBS = ''
LDB_MAP_SRC = bld.SUBDIR('ldb_map',
'ldb_map.c ldb_map_inbound.c ldb_map_outbound.c')
@@ -230,6 +150,13 @@ def build(bld):
if bld.PYTHON_BUILD_IS_ENABLED():
if not bld.CONFIG_SET('USING_SYSTEM_PYLDB_UTIL'):
for env in bld.gen_python_environments(['PKGCONFIGDIR']):
+ # we're not currently linking against the ldap libs, but ldb.pc.in
+ # has @LDAP_LIBS@
+ bld.env.LDAP_LIBS = ''
+
+ if not 'PACKAGE_VERSION' in bld.env:
+ bld.env.PACKAGE_VERSION = VERSION
+ bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig'
name = bld.pyembed_libname('pyldb-util')
bld.SAMBA_LIBRARY(name,
@@ -380,47 +307,12 @@ def build(bld):
bld.SAMBA_MODULE('ldb_tdb',
bld.SUBDIR('ldb_tdb',
- '''ldb_tdb_init.c'''),
- init_function='ldb_tdb_init',
- module_init_name='ldb_init_module',
- internal_module=False,
- deps='tdb ldb ldb_key_value',
- subsystem='ldb')
-
- bld.SAMBA_LIBRARY('ldb_key_value',
- bld.SUBDIR('ldb_tdb',
'''ldb_tdb.c ldb_search.c ldb_index.c
ldb_cache.c ldb_tdb_wrap.c'''),
- private_library=True,
- deps='tdb ldb')
-
- if bld.CONFIG_SET('HAVE_LMDB'):
- bld.SAMBA_MODULE('ldb_mdb',
- bld.SUBDIR('ldb_mdb',
- '''ldb_mdb_init.c'''),
- init_function='ldb_mdb_init',
- module_init_name='ldb_init_module',
- internal_module=False,
- deps='ldb ldb_key_value ldb_mdb_int',
- subsystem='ldb')
-
- bld.SAMBA_LIBRARY('ldb_mdb_int',
- bld.SUBDIR('ldb_mdb',
- '''ldb_mdb.c '''),
- private_library=True,
- deps='ldb lmdb ldb_key_value')
- lmdb_deps = ' ldb_mdb_int'
- else:
- lmdb_deps = ''
-
-
- bld.SAMBA_MODULE('ldb_ldb',
- bld.SUBDIR('ldb_ldb',
- '''ldb_ldb.c'''),
- init_function='ldb_ldb_init',
+ init_function='ldb_tdb_init',
module_init_name='ldb_init_module',
internal_module=False,
- deps='ldb ldb_key_value' + lmdb_deps,
+ deps='tdb ldb',
subsystem='ldb')
# have a separate subsystem for common/ldb.c, so it can rebuild
@@ -440,14 +332,8 @@ def build(bld):
bld.SAMBA_BINARY('ldbtest', 'tools/ldbtest.c', deps='ldb-cmdline ldb',
install=False)
- if bld.CONFIG_SET('HAVE_LMDB'):
- lmdb_deps = ' lmdb'
- else:
- lmdb_deps = ''
# ldbdump doesn't get installed
- bld.SAMBA_BINARY('ldbdump',
- 'tools/ldbdump.c',
- deps='ldb-cmdline ldb' + lmdb_deps,
+ bld.SAMBA_BINARY('ldbdump', 'tools/ldbdump.c', deps='ldb-cmdline ldb',
install=False)
bld.SAMBA_LIBRARY('ldb-cmdline',
@@ -461,67 +347,17 @@ def build(bld):
deps='cmocka ldb',
install=False)
- bld.SAMBA_BINARY('ldb_tdb_guid_mod_op_test',
- source='tests/ldb_mod_op_test.c',
- cflags='-DTEST_BE=\"tdb\" -DGUID_IDX=1',
- deps='cmocka ldb',
- install=False)
-
- bld.SAMBA_BINARY('ldb_tdb_kv_ops_test',
- source='tests/ldb_kv_ops_test.c',
- cflags='-DTEST_BE=\"tdb\"',
- deps='cmocka ldb',
- install=False)
-
- bld.SAMBA_BINARY('ldb_tdb_test',
- source='tests/ldb_tdb_test.c',
- deps='cmocka ldb',
- install=False)
-
bld.SAMBA_BINARY('ldb_msg_test',
source='tests/ldb_msg.c',
deps='cmocka ldb',
install=False)
- bld.SAMBA_BINARY('test_ldb_qsort',
- source='tests/test_ldb_qsort.c',
- deps='cmocka ldb',
- install=False)
-
- if bld.CONFIG_SET('HAVE_LMDB'):
- bld.SAMBA_BINARY('ldb_mdb_mod_op_test',
- source='tests/ldb_mod_op_test.c',
- cflags='-DTEST_BE=\"mdb\" -DGUID_IDX=1 '
- + '-DTEST_LMDB=1',
- deps='cmocka ldb lmdb',
- install=False)
-
- bld.SAMBA_BINARY('ldb_lmdb_test',
- source='tests/ldb_lmdb_test.c',
- deps='cmocka ldb',
- install=False)
-
- bld.SAMBA_BINARY('ldb_lmdb_size_test',
- source='tests/ldb_lmdb_size_test.c',
- deps='cmocka ldb',
- install=False)
-
- bld.SAMBA_BINARY('ldb_mdb_kv_ops_test',
- source='tests/ldb_kv_ops_test.c',
- cflags='-DTEST_BE=\"mdb\"',
- deps='cmocka ldb',
- install=False)
-
def test(ctx):
'''run ldb testsuite'''
import Utils, samba_utils, shutil
env = samba_utils.LOAD_ENVIRONMENT()
ctx.env = env
- if not env.HAVE_LMDB:
- raise Utils.WafError('make test called, but ldb was built '
- '--without-ldb-lmdb')
-
test_prefix = "%s/st" % (Utils.g_module.blddir)
shutil.rmtree(test_prefix, ignore_errors=True)
os.makedirs(test_prefix)
@@ -543,21 +379,8 @@ def test(ctx):
print("Python testsuite returned %d" % pyret)
cmocka_ret = 0
- test_exes = ['test_ldb_qsort',
- 'ldb_msg_test',
- 'ldb_tdb_mod_op_test',
- 'ldb_tdb_guid_mod_op_test',
- 'ldb_msg_test',
- 'ldb_tdb_kv_ops_test',
- 'ldb_tdb_test',
- 'ldb_mdb_mod_op_test',
- 'ldb_lmdb_test',
- # we don't want to run ldb_lmdb_size_test (which proves we can
- # fit > 4G of data into the DB), it would fill up the disk on
- # many of our test instances
- 'ldb_mdb_kv_ops_test']
-
- for test_exe in test_exes:
+ for test_exe in ['ldb_tdb_mod_op_test',
+ 'ldb_msg_test']:
cmd = os.path.join(Utils.g_module.blddir, test_exe)
cmocka_ret = cmocka_ret or samba_utils.RUN_COMMAND(cmd)